View Javadoc
1   package de.matthias_burbach.mosaique.core.parser;
2   
3   import java.io.InputStreamReader;
4   import java.io.OutputStreamWriter;
5   import java.net.URL;
6   import java.util.ArrayList;
7   import java.util.Iterator;
8   import java.util.List;
9   
10  import au.id.jericho.lib.html.Attribute;
11  import au.id.jericho.lib.html.Attributes;
12  import au.id.jericho.lib.html.Element;
13  import au.id.jericho.lib.html.Source;
14  import au.id.jericho.lib.html.Util;
15  
16  import de.matthias_burbach.mosaique.core.model.Context;
17  import de.matthias_burbach.mosaique.core.model.LogicalPage;
18  import de.matthias_burbach.mosaique.core.model.StrutsConfig;
19  import de.matthias_burbach.mosaique.core.util.FileUtils;
20  
21  /***
22   * @author Matthias Burbach
23   */
24  public class StrutsConfigParser {
25      /***
26       * Parses a Struts configuration from a file into the internal
27       * representation.
28       *
29       * @param path The full path of the Struts config to parse.
30       * @param context The context to inject into parsed objects.
31       * @return The internal representation of the successfully parsed config.
32       * @throws Exception if anything goes wrong
33       */
34      public StrutsConfig parse(
35              final String path,
36              final Context context)
37              throws Exception {
38          StrutsConfig strutsConfig = new StrutsConfig();
39          try {
40              URL sourceUrl = new URL("file:" + path);
41              String htmlText = Util.getString(
42                      new InputStreamReader(sourceUrl.openStream()));
43              Source source = new Source(htmlText);
44              source.setLogWriter(new OutputStreamWriter(System.err));
45  
46              String name = FileUtils.getNameWithoutPath(path);
47              strutsConfig.setName(name);
48              strutsConfig.setFilePath(path);
49              strutsConfig.setBegin(1);
50              strutsConfig.setEnd(1);
51              List logicalPages = parseLogicalPages(source, path, context);
52              strutsConfig.setLogicalPages(logicalPages);
53              List definitionConfigValues = parseDefinitionsConfigValues(source);
54              strutsConfig.setDefinitionsConfigValues(definitionConfigValues);
55          } catch (Exception e) {
56              e.printStackTrace();
57              strutsConfig.setErroneous(true);
58              strutsConfig.setMessage(
59                      "Could not successfully parse this config.");
60          }
61          return strutsConfig;
62      }
63  
64      /***
65       * Parses the action elements that forward to a Tile in the
66       * Struts config currently being parsed.
67       * <p/>
68       * Currently, only accepts certain action elements that comply with a
69       * special naming and attribute convention!
70       *
71       * @param source The Struts config XML document currenly being parsed.
72       * @param filePath The full path of the config being parsed.
73       * @param context The context to inject into parsed objects.
74       * @return The list of logical pages of type {@link LogicalPage}.
75       * @throws Exception if anything goes wrong
76       */
77      private List parseLogicalPages(
78              final Source source,
79              final String filePath,
80              final Context context) throws Exception {
81          List logicalPages = new ArrayList();
82          List actionElements = source.findAllElements("action");
83          for (Iterator iter = actionElements.iterator(); iter.hasNext();) {
84              Element actionElement = (Element) iter.next();
85              if (isLogicalPage(actionElement)) {
86                  LogicalPage logicalPage = new LogicalPage(context);
87                  try {
88                      Attributes attributes = actionElement.getAttributes();
89                      Attribute pathAttribute = attributes.get("path");
90                      /*
91                       * parse name
92                       */
93                      String path = pathAttribute.getValue();
94                      String name = path.substring(
95                              "/Page.".length(),
96                              path.length() - ".doDisplay".length());
97                      logicalPage.setName(name);
98                      logicalPage.setFilePath(filePath);
99                      logicalPage.setBegin(actionElement.getBegin());
100                     logicalPage.setEnd(actionElement.getEnd());
101                     /*
102                      * parse forward
103                      */
104                     Attribute forwardAttribute = attributes.get("forward");
105                     String forward = forwardAttribute.getValue();
106                     logicalPage.setForward(forward);
107                 } catch (Exception e) {
108                     e.printStackTrace();
109                     System.err.println("file:" + filePath);
110                     System.err.println("logicalPage:" + logicalPage.getName());
111                     logicalPage.setErroneous(true);
112                     logicalPage.setMessage(
113                         "Could not successfully parse this logical page.");
114                 }
115                 logicalPages.add(logicalPage);
116             }
117         }
118         return logicalPages;
119     }
120 
121     /***
122      * Distinguishes action mappings forwarding to a Tile from all others
123      * by special naming and attribute conventions which are only valid
124      * in Struts configurations generated with
125      * <a href="http://flux4eclipse.sourceforge.net">Flux</a>.
126      *
127      * @param actionElement The action element to check.
128      * @return <code>true</code> if it represents a logical page forwarding to
129      *         a Tile.
130      */
131     private boolean isLogicalPage(final Element actionElement) {
132         boolean result = false;
133         Attributes attributes = actionElement.getAttributes();
134         Attribute pathAttribute = attributes.get("path");
135         Attribute forwardAttribute = attributes.get("forward");
136         if (pathAttribute != null && forwardAttribute != null
137                 && pathAttribute.getValue().startsWith("/Page.")
138                 && pathAttribute.getValue().endsWith(".doDisplay")
139                 && !forwardAttribute.getValue().startsWith("/Page.")
140                 && !forwardAttribute.getValue().startsWith("/Action.")) {
141             result = true;
142         }
143         return result;
144     }
145 
146     /***
147      * Parses the file names of the plugged-in Tiles configurations in the
148      * Struts config currently being parsed.
149      *
150      * @param source The Struts config XML document currenly being parsed.
151      * @return The list of relative file paths of type {@link String}.
152      * @throws Exception if anything goes wrong
153      */
154     private List parseDefinitionsConfigValues(
155             final Source source) throws Exception {
156         List paths = new ArrayList();
157         List setPropertyElements = source.findAllElements("set-property");
158         for (Iterator iter = setPropertyElements.iterator(); iter.hasNext();) {
159             Element setPropertyElement = (Element) iter.next();
160             Attributes attributes = setPropertyElement.getAttributes();
161             Attribute propertyAttribute = attributes.get("property");
162             if (propertyAttribute.getValue().equals("definitions-config")) {
163                 String value = attributes.get("value").getValue();
164                 String[] pathsAsArray = value.split(",");
165                 for (int i = 0; i < pathsAsArray.length; i++) {
166                     String path = pathsAsArray[i].trim();
167                     if (path.length() > 0) {
168                         paths.add(path);
169                     }
170                 }
171             }
172         }
173         return paths;
174     }
175 }