1 package org.astrogrid.portal.transformation;
2
3 import java.io.File;
4 import java.io.FilenameFilter;
5 import java.io.IOException;
6 import java.net.MalformedURLException;
7 import java.net.URI;
8 import java.net.URL;
9 import java.util.Map;
10 import java.util.regex.Pattern;
11
12 import org.apache.avalon.framework.logger.Logger;
13 import org.apache.avalon.framework.parameters.Parameters;
14 import org.apache.cocoon.ProcessingException;
15 import org.apache.cocoon.environment.SourceResolver;
16 import org.apache.cocoon.transformation.AbstractDOMTransformer;
17 import org.apache.commons.jxpath.JXPathContext;
18 import org.apache.commons.jxpath.xml.DocumentContainer;
19 import org.apache.excalibur.source.Source;
20 import org.w3c.dom.Document;
21 import org.w3c.dom.Element;
22 import org.xml.sax.SAXException;
23
24 /***
25 * Add the non-specified menus to the main menu.
26 */
27 public class MenuTransformer extends AbstractDOMTransformer {
28 private String menuDirectory = null;
29 private String menuHref = null;
30
31
32
33
34 public void setup(SourceResolver resolver, Map objectModel, String src, Parameters params)
35 throws ProcessingException, SAXException, IOException {
36 super.setup(resolver, objectModel, src, params);
37
38 Logger logger = this.getLogger();
39 logger.info("[setup]");
40
41 menuDirectory = resolveMenuDirectory(resolver, params);
42
43 logger.info("[setup] menu href: " + menuHref);
44 }
45
46
47
48
49 protected Document transform(Document doc) {
50 Document result = doc;
51
52 Logger logger = this.getLogger();
53
54
55
56
57
58
59
60 logger.info("[transform] create menu element");
61
62
63
64
65
66
67
68 logger.info("[transform] created menu link element");
69
70 Element rootMenuEl = (Element) result.getFirstChild();
71
72
73 logger.info("[transform] added new menu to main menu");
74
75 result = addMenus(result, rootMenuEl, doc);
76
77 logger.info("[transform] added sub menus");
78
79 return result;
80 }
81
82 private Document addMenus(Document doc, Element menuEl, Document sourceDoc) {
83 Document result = doc;
84
85 Logger logger = this.getLogger();
86
87 File menuFile = null;
88 Element xIncludeEl = null;
89 File[] menuFiles = null;
90
91 try {
92 menuFiles = listMenuFiles(menuDirectory);
93 }
94 catch(Throwable t) {
95
96 }
97
98 logger.info("[addMenus] menu files: " + menuFiles);
99
100 if(menuFiles != null) {
101 for (int fileIndex = 0; fileIndex < menuFiles.length; fileIndex++) {
102 menuFile = menuFiles[fileIndex];
103
104 xIncludeEl =
105 result.createElementNS("http://www.w3.org/2001/XInclude", "xi:include");
106 xIncludeEl.setAttribute("href", menuDirectory + menuFile.getName());
107
108 if(testMenuInclude(sourceDoc.getDocumentElement(), menuFile)) {
109 menuEl.appendChild(xIncludeEl);
110 }
111 }
112 }
113 else {
114 logger.debug("[addMenus] no files... directory: " + menuDirectory);
115 }
116
117 return result;
118 }
119
120 private File[] listMenuFiles(String menuDirectory) throws Throwable {
121 final Logger logger = this.getLogger();
122
123 try {
124 File menuDirectoryFile = new File(menuDirectory);
125
126 return menuDirectoryFile.listFiles(new FilenameFilter() {
127 public boolean accept(File dir, String name) {
128 logger.info("[FilenameFilter.accept] dir: " + dir + ", name: " + name);
129 if (name.equals("menu.xml")) {
130 return false;
131 }
132
133 return Pattern.matches(".*//.xml", name);
134 }
135 });
136 }
137 catch(Throwable t) {
138 logger.debug("[listMenuFiles]", t);
139 throw t;
140 }
141 }
142
143 private boolean testMenuInclude(Element menu, File toInclude) {
144 boolean result = false;
145
146 try {
147 URL includeUrl = toInclude.toURL();
148
149 JXPathContext menuContext = JXPathContext.newContext(menu);
150 JXPathContext fileContext = JXPathContext.newContext(new DocumentContainer(includeUrl));
151
152 String fileMenuName = (String) fileContext.getValue("/agp:menu-def/@name");
153 Double menuValue = (Double) menuContext.getValue("count(//agp:menu-def[@name='" + fileMenuName + "'])");
154
155 result = (menuValue.doubleValue() == 0.0d);
156 }
157 catch(MalformedURLException e) {
158 result = false;
159 }
160
161 return result;
162 }
163
164 private String resolveMenuDirectory(SourceResolver resolver, Parameters params)
165 throws MalformedURLException, IOException {
166 String menuDirectoryParam = params.getParameter("menu-directory", "");
167 Source menuDirectorySource = resolver.resolveURI(menuDirectoryParam);
168 String menuDirectoryURI = menuDirectorySource.getURI();
169 URI uri = URI.create(menuDirectoryURI);
170
171 return uri.getPath();
172 }
173 }