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
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
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 }