View Javadoc

1   package de.matthias_burbach.mosaique4eclipse.views;
2   
3   import java.io.File;
4   import java.util.HashMap;
5   import java.util.Iterator;
6   import java.util.List;
7   import java.util.Map;
8   
9   import org.eclipse.core.resources.IFile;
10  import org.eclipse.core.resources.IFolder;
11  import org.eclipse.core.resources.IWorkspaceRoot;
12  import org.eclipse.core.resources.ResourcesPlugin;
13  import org.eclipse.core.runtime.IAdaptable;
14  import org.eclipse.jface.viewers.ITreeContentProvider;
15  import org.eclipse.jface.viewers.Viewer;
16  import org.eclipse.ui.model.IWorkbenchAdapter;
17  
18  import de.matthias_burbach.mosaique.core.model.Context;
19  import de.matthias_burbach.mosaique.core.model.DefinitionResolver;
20  import de.matthias_burbach.mosaique.core.model.JspResolver;
21  import de.matthias_burbach.mosaique.core.model.PathFinder;
22  import de.matthias_burbach.mosaique.core.model.StrutsConfig;
23  import de.matthias_burbach.mosaique.core.model.TilesDefinitions;
24  import de.matthias_burbach.mosaique.core.parser.StrutsConfigParser;
25  import de.matthias_burbach.mosaique.core.parser.TilesDefinitionsParser;
26  import de.matthias_burbach.mosaique.swing.BaseMutableTreeNode;
27  import de.matthias_burbach.mosaique.swing.LogicalPageNode;
28  import de.matthias_burbach.mosaique.swing.StrutsConfigNode;
29  import de.matthias_burbach.mosaique4eclipse.util.Util;
30  
31  /***
32   * The content provider class is responsible for providing objects to the
33   * view. It can wrap existing objects in adapters or simply return objects
34   * as-is. These objects may be sensitive to the current input of the view,
35   * or ignore it and always show the same content (like Task List, for
36   * example).
37   */
38  class MosaiqueTreeContentProvider implements ITreeContentProvider {
39      /***
40       * Maps IFile representations of Struts config files to objects of type
41       * {@link StrutsConfigNode}.
42       */
43      private Map strutsConfigNodes = new HashMap();
44  
45      /***
46       * Maps IFolder representations of WEB-INF folders
47       * (=parents of IFiles of Struts config files) to objects of type
48       * {@link de.matthias_burbach.mosaique.core.model.Context}.
49       */
50      private Map contexts = new HashMap();
51  
52      /***
53       * The parser for Tiles definition files. The instance is stateless and
54       * can be re-used therefore.
55       */
56      private TilesDefinitionsParser tilesDefParser =
57          new TilesDefinitionsParser();
58  
59      /*
60       * (non-Javadoc)
61       * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(
62       *          java.lang.Object)
63       */
64      /***
65       * {@inheritDoc}
66       */
67      public boolean hasChildren(final Object element) {
68          boolean result = false;
69          Object[] children = getChildren(element);
70          if (children != null && children.length > 0) {
71              result = true;
72          }
73          return result;
74      }
75  
76      /*
77       * (non-Javadoc)
78       * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
79       *          java.lang.Object)
80       */
81      /***
82       * {@inheritDoc}
83       */
84      public Object[] getElements(final Object inputElement) {
85          return getChildren(inputElement);
86      }
87  
88      /*
89       * (non-Javadoc)
90       * @see org.eclipse.jface.viewers.IContentProvider#dispose()
91       */
92      /***
93       * {@inheritDoc}
94       */
95      public void dispose() {
96          // TODO Auto-generated method stub
97      }
98  
99      /*
100      * (non-Javadoc)
101      * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(
102      *          org.eclipse.jface.viewers.Viewer,
103      *          java.lang.Object,
104      *          java.lang.Object)
105      */
106     /***
107      * {@inheritDoc}
108      */
109     public void inputChanged(
110             final Viewer viewer,
111             final Object oldInput,
112             final Object newInput) {
113         // nothing to do
114     }
115 
116     /*
117      * (non-Javadoc)
118      * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(
119      *          java.lang.Object)
120      */
121     /***
122      * {@inheritDoc}
123      */
124     public Object getParent(final Object child) {
125         Object result = null;
126         if (child instanceof LogicalPageNode) {
127             LogicalPageNode node = (LogicalPageNode) child;
128             result = Util.fileToIFile(
129                         new File(node.getFileItem().getFilePath()));
130         } else if (child instanceof BaseMutableTreeNode) {
131             result = ((BaseMutableTreeNode) child).getParent();
132         } else {
133             IWorkbenchAdapter adapter = getAdapter(child);
134             if (adapter != null) {
135                 result = adapter.getParent(child);
136             }
137         }
138         return result;
139     }
140 
141     /*
142      * (non-Javadoc)
143      * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(
144      *          java.lang.Object)
145      */
146     /***
147      * {@inheritDoc}
148      */
149     public Object[] getChildren(final Object aParent) {
150         Object[] result = null;
151         Object parent = aParent;
152         if (parent == null) {
153             parent = getRoot();
154         }
155         if (Util.isStrutsConfigFile(parent)) {
156             IFile strutsConfigIFile = (IFile) parent;
157             StrutsConfigNode strutsConfigNode =
158                 (StrutsConfigNode) strutsConfigNodes.get(strutsConfigIFile);
159             if (strutsConfigNode == null) {
160                 Context context = getContext(strutsConfigIFile);
161                 String path = strutsConfigIFile.getLocation().toOSString();
162                 StrutsConfigParser parser = new StrutsConfigParser();
163                 try {
164                     StrutsConfig strutsConfig = parser.parse(path, context);
165                     if (!strutsConfig.isErroneous()) {
166                         parseTilesDefinitions(
167                                 strutsConfigIFile,
168                                 strutsConfig.getDefinitionsConfigValues(),
169                                 context);
170                     }
171                     strutsConfigNode = new StrutsConfigNode(
172                             strutsConfig, null);
173                     strutsConfigNodes.put(strutsConfigIFile, strutsConfigNode);
174                 } catch (Exception e) {
175                     e.printStackTrace();
176                 }
177             }
178             if (strutsConfigNode != null) {
179                 result = strutsConfigNode.getChildren();
180             }
181         } else if (parent instanceof BaseMutableTreeNode) {
182             result = ((BaseMutableTreeNode) parent).getChildren();
183         } else {
184             IWorkbenchAdapter adapter = getAdapter(parent);
185             if (adapter != null) {
186                 result = adapter.getChildren(parent);
187             }
188         }
189         return result;
190     }
191 
192     /***
193      * @return The root object of the tree provided.
194      */
195     IWorkspaceRoot getRoot() {
196         IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
197         return root;
198     }
199 
200     /***
201      * Refreshes the provided tree from scratch by discarding all cache
202      * contents. Actual refreshing will take place on next access to the tree
203      * elements.
204      */
205     void refresh() {
206         strutsConfigNodes.clear();
207         contexts.clear();
208     }
209 
210     /***
211      * @param strutsConfigIFile The Struts configuration file to derive the
212      *                          context from.
213      * @return The context of cacheable instances.
214      */
215     private Context getContext(final IFile strutsConfigIFile) {
216         IFolder webInfFolder = (IFolder) strutsConfigIFile.getParent();
217         Context context = (Context) contexts.get(webInfFolder);
218         if (context == null) {
219             context = new Context();
220             DefinitionResolver definitionResolver = new DefinitionResolver();
221             context.setDefinitionResolver(definitionResolver);
222             PathFinder pathFinder = new VrpEclipsePathFinder(strutsConfigIFile);
223             JspResolver jspResolver = new JspResolver(pathFinder, context);
224             context.setJspResolver(jspResolver);
225             contexts.put(webInfFolder, context);
226         }
227         return context;
228     }
229 
230     /***
231      * Returns the implementation of IWorkbenchAdapter for the given object.
232      * Returns null if the adapter is not defined or the object is not
233      * adaptable.
234      *
235      * @param element the element to be adapted
236      * @return the corresponding workbench adapter object or <code>null</code>.
237      */
238     private IWorkbenchAdapter getAdapter(final Object element) {
239         IWorkbenchAdapter result = null;
240         if (element instanceof IAdaptable) {
241             result = (IWorkbenchAdapter) ((IAdaptable) element)
242                     .getAdapter(IWorkbenchAdapter.class);
243         }
244         return result;
245     }
246 
247     /***
248      * @param strutsConfigIFile The Struts configuration that links to the Tiles
249      *                          to be parsed.
250      * @param definitionsConfigValues The relative paths of the Tiles definition
251      *                                files to parse.
252      * @param context The context of cacheable instances.
253      * @throws Exception if anything goes wrong.
254      */
255     private void parseTilesDefinitions(
256             final IFile strutsConfigIFile,
257             final List definitionsConfigValues,
258             final Context context) throws Exception {
259         PathFinder pathFinder = new VrpEclipsePathFinder(strutsConfigIFile);
260         DefinitionResolver resolver = context.getDefinitionResolver();
261         Iterator iter = definitionsConfigValues.iterator();
262         while (iter.hasNext()) {
263             String value = (String) iter.next();
264             String path = pathFinder.findAbsolutePath(value);
265             if (path != null) {
266                 TilesDefinitions tilesDefinitions =
267                     tilesDefParser.parse(path, context);
268                 resolver.addTilesDefinitions(tilesDefinitions);
269             }
270         }
271     }
272 
273     /***
274      * Checks if the Struts config node corresponding to the Struts file object
275      * has errors.
276      *
277      * @param strutsConfigIFile The Struts config file to be mapped to the
278      *                          Struts config node to be checked.
279      * @return <code>true</code> if the node exists and is erroneous.
280      */
281     boolean isErroneousStrutsConfig(final IFile strutsConfigIFile) {
282         boolean result = false;
283         StrutsConfigNode strutsConfigNode =
284             (StrutsConfigNode) strutsConfigNodes.get(strutsConfigIFile);
285         if (strutsConfigNode != null && strutsConfigNode.isErroneous()) {
286             result = true;
287         }
288         return result;
289     }
290 }