Initialize
[sdk/ide/product.git] / org.eclipse.jst.pagedesigner / src / org / eclipse / jst / pagedesigner / properties / DesignerPropertyTool.java
1 /*******************************************************************************\r
2  * Copyright (c) 2006 Sybase, Inc. and others.\r
3  *\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Sybase, Inc. - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.eclipse.jst.pagedesigner.properties;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Arrays;\r
16 import java.util.List;\r
17 \r
18 import org.eclipse.core.resources.IProject;\r
19 import org.eclipse.core.resources.IProjectNature;\r
20 import org.eclipse.gef.editparts.AbstractEditPart;\r
21 import org.eclipse.gef.ui.parts.GraphicalEditor;\r
22 import org.eclipse.jdt.core.IJavaProject;\r
23 import org.eclipse.jdt.core.JavaCore;\r
24 import org.eclipse.jface.text.ITextSelection;\r
25 import org.eclipse.jface.viewers.ISelection;\r
26 import org.eclipse.jface.viewers.IStructuredSelection;\r
27 import org.eclipse.jst.pagedesigner.IHTMLConstants;\r
28 import org.eclipse.jst.pagedesigner.PDPlugin;\r
29 import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;\r
30 import org.eclipse.jst.pagedesigner.dom.DOMUtil;\r
31 import org.eclipse.jst.pagedesigner.editors.HTMLEditor;\r
32 import org.eclipse.jst.pagedesigner.utils.SelectionHelper;\r
33 import org.eclipse.jst.pagedesigner.viewer.DesignRange;\r
34 import org.eclipse.ui.IEditorPart;\r
35 import org.eclipse.ui.IWorkbenchPart;\r
36 import org.eclipse.ui.editors.text.TextEditor;\r
37 import org.eclipse.ui.views.contentoutline.ContentOutline;\r
38 import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;\r
39 import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;\r
40 import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;\r
41 import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;\r
42 import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;\r
43 import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;\r
44 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;\r
45 import org.w3c.dom.Attr;\r
46 import org.w3c.dom.CDATASection;\r
47 import org.w3c.dom.Element;\r
48 import org.w3c.dom.NamedNodeMap;\r
49 import org.w3c.dom.Node;\r
50 import org.w3c.dom.Text;\r
51 \r
52 /**\r
53  * This is util class most used by Property related operation.\r
54  * \r
55  * @author mengbo\r
56  */\r
57 public class DesignerPropertyTool {\r
58         \r
59         /**\r
60          * @param fNode\r
61          * @param attributeDesc\r
62          * @return attribute value\r
63          */\r
64         public static String getAttributeValue(Element fNode, CMNode attributeDesc) {\r
65                 if (attributeDesc == null) {\r
66                         return ""; //$NON-NLS-1$\r
67                 }\r
68                 String returnedValue = ""; //$NON-NLS-1$\r
69                 NamedNodeMap attrMap = fNode.getAttributes();\r
70                 if (attrMap != null) {\r
71                         Node attribute = attrMap.getNamedItem(attributeDesc.getNodeName());\r
72                         if (attribute != null) {\r
73                                 if (attribute instanceof IDOMNode) {\r
74                                         returnedValue = ((IDOMNode) attribute).getValueSource();\r
75                                 } else {\r
76                                         returnedValue = attribute.getNodeValue();\r
77                                 }\r
78                         }\r
79                 }\r
80                 return returnedValue;\r
81         }\r
82 \r
83 //      /**\r
84 //       * @param fNode\r
85 //       * @param filter\r
86 //       * @return array of attributes as objects\r
87 //   * (unused) \r
88 //       */\r
89 //      public static Object[] getElementReferedAttributes(Element fNode,\r
90 //                      String[] filter) {\r
91 //              List result = new ArrayList();\r
92 //              CMNamedNodeMap cmnnm = getElementDeclaredAttributes(fNode);\r
93 //              for (int i = 0, n = cmnnm.getLength(); i < n; i++) {\r
94 //                      String name = cmnnm.item(i).getNodeName();\r
95 //                      if (Arrays.asList(filter).contains(name)) {\r
96 //                              result.add(cmnnm.item(i));\r
97 //                      }\r
98 //              }\r
99 //              return result.toArray(new CMNode[result.size()]);\r
100 //      }\r
101 \r
102         /**\r
103          * @param fNode\r
104          * @return CMNamedNodeMap\r
105          */\r
106         public static CMNamedNodeMap getElementDeclaredAttributes(Node fNode) {\r
107                 IStructuredModel structModel = null;\r
108                 if (fNode instanceof IDOMNode) {\r
109                         structModel = ((IDOMNode) fNode).getModel();\r
110                 }\r
111                 if (null == structModel) {\r
112                         return null;\r
113                 }\r
114                 CMElementDeclaration cmde = null;\r
115                 CMNamedNodeMap cmnnm = null;\r
116                 if (fNode == null || fNode.getNodeType() != Node.ELEMENT_NODE) {\r
117                         cmde = null;\r
118                 }\r
119                 ModelQuery modelQuery = ModelQueryUtil.getModelQuery(fNode\r
120                                 .getOwnerDocument());\r
121                 if (modelQuery != null) {\r
122                         cmde = modelQuery.getCMElementDeclaration((Element) fNode);\r
123                 }\r
124                 if (cmde != null) {\r
125                         cmnnm = cmde.getAttributes();\r
126                 }\r
127                 return cmnnm;\r
128         }\r
129 \r
130         /**\r
131          * the selection could be different kinds of selection, including: 1.\r
132          * ITextSelection 2. IStructuredSelection (Node) 3. IStructuredSelection\r
133          * (EditPart) 4. DesignRange we want to normalize it to only #2. If the node\r
134          * is ATTR or TEXT/CDATA_SECTION, will use it's parent node.\r
135          * \r
136          * @param selectingPart\r
137          * @param selection\r
138          * @param htmlEditor\r
139          * @return null if can't normalize.\r
140          */\r
141         public static Node normalizeSelectionToElement(\r
142                         IWorkbenchPart selectingPart, ISelection selection,\r
143                         HTMLEditor htmlEditor) {\r
144                 \r
145                 Node node = null;\r
146                 if (selectingPart instanceof HTMLEditor) {\r
147                         IEditorPart part = ((HTMLEditor) selectingPart).getActiveEditor();\r
148                         if (part instanceof TextEditor) {\r
149                                 if (selection instanceof ITextSelection) {\r
150                                         IStructuredModel model = ((HTMLEditor) selectingPart)\r
151                                                         .getModel();\r
152                                         node = SelectionHelper.toNode(model,\r
153                                                         (ITextSelection) selection);\r
154                                 }\r
155                         } else if (part instanceof GraphicalEditor) {\r
156                                 if (selection instanceof IStructuredSelection) {\r
157                                         node = SelectionHelper\r
158                                                         .toNode((IStructuredSelection) selection);\r
159                                 } else if (selection instanceof DesignRange) {\r
160                                         node = SelectionHelper.toNode((DesignRange) selection);\r
161                                 }\r
162                         }\r
163                         if (node instanceof Attr) {\r
164                                 node = ((Attr) node).getOwnerElement();\r
165                         } else if (node instanceof Text || node instanceof CDATASection) {\r
166                                 node = node.getParentNode();\r
167                         }\r
168                 } else if (selectingPart instanceof ContentOutline) {\r
169                         if (selection instanceof IStructuredSelection\r
170                                         && ((ContentOutline) selectingPart).getCurrentPage() != null\r
171                                         && ((ContentOutline) selectingPart).getCurrentPage()\r
172                                                         .getControl().isFocusControl()) {\r
173                                 node = SelectionHelper.toNode((IStructuredSelection) selection);\r
174                                 if (node == null) {\r
175                                         node = htmlEditor.getDOMDocument();\r
176                                 }\r
177                         }\r
178                 }\r
179 \r
180                 return node;\r
181         }\r
182 \r
183         /**\r
184          * @param node as Object\r
185          * @return element \r
186          */\r
187         public static Element getElementNode(Object node) {\r
188                 Object model;\r
189                 Element element = null;\r
190                 if (node == null) {\r
191                         return null;\r
192                 }\r
193 \r
194                 if (node instanceof Element) {\r
195                         element = (Element) node;\r
196                 } else if (node instanceof AbstractEditPart) {\r
197                         model = ((AbstractEditPart) node).getModel();\r
198                         if (model instanceof Element) {\r
199                                 element = (Element) model;\r
200                         }\r
201                 } else if (node instanceof ISelection) {\r
202                         element = getElement(null, (ISelection) node);\r
203                 }\r
204                 return element;\r
205         }\r
206 \r
207         /**\r
208          * @param element\r
209          * @param filter\r
210          * @return list of attribute names\r
211          */\r
212         public static List getNameList(Element element, String[] filter) {\r
213                 List result = new ArrayList();\r
214                 CMNamedNodeMap attributes = getElementDeclaredAttributes(element);\r
215                 if (attributes != null) {\r
216                         for (int i = 0, n = attributes.getLength(); i < n; i++) {\r
217                                 String name = attributes.item(i).getNodeName();\r
218                                 if (Arrays.asList(filter).contains(name))\r
219                                         result.add(name);\r
220                         }\r
221                 }\r
222                 return result;\r
223         }\r
224 \r
225         /**\r
226          * @param selection\r
227          *            should be a normalized selection\r
228          * @return node\r
229          */\r
230         public static Node getCommonParent(ISelection selection) {\r
231                 if (selection instanceof IStructuredSelection) {\r
232                         Object obj = ((IStructuredSelection) selection).getFirstElement();\r
233                         return (Node) obj;\r
234                 } else if (selection instanceof DesignRange) {\r
235                         DesignRange range = (DesignRange) selection;\r
236                         Node node1 = range.getStartPosition().getContainerNode();\r
237                         Node node2 = range.getEndPosition().getContainerNode();\r
238                         return DOMUtil.findCommonAncester(node1, node2);\r
239                 } else {\r
240                         // should not happen\r
241                         return null;\r
242                 }\r
243         }\r
244 \r
245         /**\r
246          * The passed in selection should be normalized selection.\r
247          * \r
248          * @param selectingPart\r
249          * @param selection\r
250          * @return element\r
251          */\r
252         public static Element getElement(IWorkbenchPart selectingPart,\r
253                         ISelection selection) {\r
254                 Node node = getCommonParent(selection);\r
255                 if (node instanceof Element) {\r
256                         return (Element) node;\r
257                 } else if (node != null) {\r
258                         node = node.getParentNode();\r
259                         if (node instanceof Element) {\r
260                                 return (Element) node;\r
261                         }\r
262                 }\r
263                 return null;\r
264         }\r
265 \r
266         // reserved for future native use.\r
267         // public static void dumpChildren(Element element)\r
268         // {\r
269         // // In this function we are using logger to dump message out.\r
270         // Logger logger = PDPlugin.getLogger(DesignerPropertyTool.class);\r
271         // if (element == null || !DEBUG)\r
272         // return;\r
273         // NodeList nl = element.getChildNodes();\r
274         // // It's our pattern for dumping message\r
275         // logger.debug("\n----------------------------"); //$NON-NLS-1$\r
276         // logger.debug("Element:" + element.getNodeName()); //$NON-NLS-1$\r
277         // for (int i = 0; i < nl.getLength(); i++)\r
278         // {\r
279         // Node node = nl.item(i);\r
280         // logger.debug("child[" + i + "]:" + node.getNodeName()); //$NON-NLS-1$\r
281         // //$NON-NLS-2$\r
282         // }\r
283         // logger.debug("----------------------------\n"); //$NON-NLS-1$\r
284         // }\r
285 \r
286         /**\r
287          * @param element\r
288          * @return bool\r
289          *  (unused)\r
290          */\r
291         public static boolean isMultiSelection(Element element) {\r
292                 if (element.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_OPTION)) {\r
293                         return element.getAttribute(ICSSPropertyID.ATTR_MULTIPLE) != null;\r
294                 }\r
295                 return false;\r
296         }\r
297 \r
298 //      /**\r
299 //       * @param element\r
300 //       * @return if elementImpl, return source, else null\r
301 //       * (unused)\r
302 //       */\r
303 //      public static String getElementTextSource(Element element) {\r
304 //              if (element == null) {\r
305 //                      return null;\r
306 //              }\r
307 //              if (element instanceof ElementImpl) {\r
308 //                      return ((ElementImpl) element).getSource();\r
309 //              }\r
310 //              return null;\r
311 //      }\r
312 \r
313         /**\r
314          * @param project\r
315          * @return IJavaProject\r
316          */\r
317         public static IJavaProject getJavaProject(Object project) {\r
318                 if (project == null) {\r
319                         return null;\r
320                 }\r
321                 if (project instanceof IJavaProject) {\r
322                         return (IJavaProject) project;\r
323                 } else if (project instanceof IProject) {\r
324                         try {\r
325                                 IProjectNature nature = ((IProject) project)\r
326                                                 .getNature(JavaCore.NATURE_ID);\r
327                                 if (nature == null) {\r
328                                         return null;\r
329                                 }\r
330                 return (IJavaProject) nature;\r
331                         } catch (Exception e) {\r
332                                 // Error.DesignerPropertyTool.NatureQuerying = Error in project\r
333                                 // java nature querying\r
334                                 PDPlugin.getLogger(DesignerPropertyTool.class).error(\r
335                                                 "Error.DesignerPropertyTool.NatureQuerying", e); //$NON-NLS-1$\r
336                                 // Should be error tolerable?\r
337                                 return null;\r
338                         }\r
339                 }\r
340                 return null;\r
341         }\r
342 //\r
343 //      /**\r
344 //       * @param project as Object\r
345 //       * @return IProject or null\r
346 //       */\r
347 //      public static IProject getProject(Object project) {\r
348 //              if (project instanceof IProject) {\r
349 //                      return (IProject) project;\r
350 //              } else if (project instanceof IJavaProject) {\r
351 //                      return ((IJavaProject) project).getProject();\r
352 //              }\r
353 //              return null;\r
354 //      }\r
355 \r
356 }\r