001: /*
002: * Hammurapi
003: * Automated Java code review system.
004: * Copyright (C) 2004 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.org
021: * e-Mail: support@hammurapi.biz
022: */
023: package org.hammurapi.inspectors.techstack;
024:
025: import java.io.File;
026: import java.io.IOException;
027: import java.util.Collection;
028: import java.util.HashMap;
029: import java.util.Iterator;
030: import java.util.Map;
031: import java.util.Properties;
032: import java.util.TreeSet;
033:
034: import javax.xml.parsers.DocumentBuilderFactory;
035: import javax.xml.parsers.FactoryConfigurationError;
036: import javax.xml.parsers.ParserConfigurationException;
037: import javax.xml.transform.TransformerException;
038:
039: import org.apache.xpath.CachedXPathAPI;
040: import org.hammurapi.ParameterizableInspectorBase;
041: import org.hammurapi.HammurapiException;
042: import org.hammurapi.results.AnnotationContext;
043: import org.hammurapi.results.LinkedAnnotation;
044: import org.hammurapi.results.AnnotationContext.FileEntry;
045: import org.w3c.dom.Document;
046: import org.w3c.dom.Element;
047: import org.w3c.dom.traversal.NodeIterator;
048:
049: import com.pavelvlasov.config.ConfigurationException;
050: import com.pavelvlasov.config.XmlSource;
051: import com.pavelvlasov.jsel.CompilationUnit;
052: import com.pavelvlasov.jsel.JselException;
053: import com.pavelvlasov.jsel.Repository;
054: import com.pavelvlasov.xml.dom.AbstractDomObject;
055: import com.pavelvlasov.xml.dom.DOMUtils;
056:
057: /**
058: * Creates annotation, which displays dependencies on external packages.
059: * @author Pavel Vlasov
060: * @version $Revision: 1.4 $
061: */
062: public class TechStackInspector extends ParameterizableInspectorBase {
063:
064: private XmlSource config;
065: private XmlSource style;
066: private XmlSource licenseSummaryStyle;
067: private XmlSource licenseClientsStyle;
068: private XmlSource productClientsStyle;
069: private XmlSource publisherClientsStyle;
070:
071: public TechStackInspector() {
072: config = new XmlSource("config", getClass(), ".xml");
073: addConfigurator(config);
074:
075: style = new XmlSource("style", getClass(), ".xsl");
076: addConfigurator(style);
077:
078: licenseSummaryStyle = new XmlSource("license-summary-style",
079: getClass(), "!licenses.xsl");
080: addConfigurator(licenseSummaryStyle);
081:
082: licenseClientsStyle = new XmlSource("license-clients-style",
083: getClass(), "!license-clients.xsl");
084: addConfigurator(licenseClientsStyle);
085:
086: productClientsStyle = new XmlSource("product-clients-style",
087: getClass(), "!product-clients.xsl");
088: addConfigurator(productClientsStyle);
089:
090: publisherClientsStyle = new XmlSource(
091: "publisher-clients-style", getClass(),
092: "!publisher-clients.xsl");
093: addConfigurator(publisherClientsStyle);
094: }
095:
096: public void leave(final Repository repo) {
097: try {
098: Document configDoc = config.getConfigDocument();
099: final TechStack techStack = configDoc == null ? new TechStack()
100: : new TechStack(configDoc.getDocumentElement());
101: Iterator it = repo.getExternalSuppliers().entrySet()
102: .iterator();
103: while (it.hasNext()) {
104: Map.Entry entry = (Map.Entry) it.next();
105: String packageName = (String) entry.getKey();
106: Collection clients = new TreeSet();
107: Iterator cit = repo.getExternalSupplierClients(
108: packageName).iterator();
109: while (cit.hasNext()) {
110: CompilationUnit cu = (CompilationUnit) cit.next();
111: String cpn = cu.getPackage().getName();
112: if (cpn.length() == 0) {
113: clients.add(cu.getName());
114: } else {
115: clients.add(cpn.replace('.', '/') + "/"
116: + cu.getName());
117: }
118: }
119: techStack.addPackage(packageName, clients);
120: }
121:
122: final Document techStackDoc = DocumentBuilderFactory
123: .newInstance().newDocumentBuilder().newDocument();
124: techStack.toDom(AbstractDomObject.addElement(techStackDoc,
125: "tech-stack"));
126:
127: context.annotate(new LinkedAnnotation() {
128: String path;
129:
130: public String getPath() {
131: return path;
132: }
133:
134: public String getName() {
135: return "Technology stack";
136: }
137:
138: public void render(AnnotationContext context)
139: throws HammurapiException {
140: if (".HTML"
141: .equalsIgnoreCase(context.getExtension())) {
142: FileEntry root = context.getNextFile(context
143: .getExtension());
144: path = root.getPath();
145: Element tsRoot = techStackDoc
146: .getDocumentElement();
147: tsRoot
148: .setAttribute("root-path", root
149: .getPath());
150:
151: FileEntry licenseSummary = context
152: .getNextFile(context.getExtension());
153: tsRoot.setAttribute("license-summary",
154: licenseSummary.getPath());
155:
156: CachedXPathAPI cxpa = new CachedXPathAPI();
157:
158: try {
159: Map params = new HashMap();
160: NodeIterator nit = cxpa
161: .selectNodeIterator(tsRoot,
162: "publisher/product[client]");
163: Element element;
164: while ((element = (Element) nit.nextNode()) != null) {
165: FileEntry fe = context
166: .getNextFile(context
167: .getExtension());
168: element.setAttribute("path", fe
169: .getPath());
170: params.put("product", element
171: .getAttribute("key"));
172: DOMUtils.style(techStackDoc, fe
173: .getFile(), productClientsStyle
174: .getStream(), params);
175: }
176:
177: nit = cxpa.selectNodeIterator(tsRoot,
178: "publisher[client]");
179: while ((element = (Element) nit.nextNode()) != null) {
180: FileEntry fe = context
181: .getNextFile(context
182: .getExtension());
183: element.setAttribute("path", fe
184: .getPath());
185: params.put("publisher", element
186: .getAttribute("key"));
187: DOMUtils.style(techStackDoc, fe
188: .getFile(),
189: publisherClientsStyle
190: .getStream(), params);
191: }
192:
193: nit = cxpa.selectNodeIterator(tsRoot,
194: "//license[client]");
195: while ((element = (Element) nit.nextNode()) != null) {
196: FileEntry fe = context
197: .getNextFile(context
198: .getExtension());
199: element.setAttribute("path", fe
200: .getPath());
201: params.put("license", element
202: .getAttribute("key"));
203: DOMUtils.style(techStackDoc, fe
204: .getFile(), licenseClientsStyle
205: .getStream(), params);
206: }
207:
208: DOMUtils.style(techStackDoc,
209: root.getFile(), style.getStream(),
210: null);
211: DOMUtils.style(techStackDoc, licenseSummary
212: .getFile(), licenseSummaryStyle
213: .getStream(), null);
214:
215: DOMUtils.serialize(techStackDoc, new File(
216: "techStack.xml"));
217: } catch (IOException e) {
218: throw new HammurapiException(
219: "Could not render tech stack to HTML: "
220: + e, e);
221: } catch (TransformerException e) {
222: throw new HammurapiException(
223: "Could not render tech stack to HTML: "
224: + e, e);
225: } catch (ConfigurationException e) {
226: throw new HammurapiException(
227: "Could not render tech stack to HTML: "
228: + e, e);
229: }
230: } else {
231: FileEntry root = context.getNextFile(context
232: .getExtension());
233: path = root.getPath();
234: try {
235: DOMUtils.serialize(techStackDoc, root
236: .getFile());
237: } catch (IOException e) {
238: throw new HammurapiException(
239: "Could not render tech stack to xml: "
240: + e, e);
241: } catch (TransformerException e) {
242: throw new HammurapiException(
243: "Could not render tech stack to xml: "
244: + e, e);
245: }
246: }
247: }
248:
249: public Properties getProperties() {
250: return null;
251: }
252: });
253:
254: getContext().getSession().setAttribute("tech-stack",
255: techStack);
256: } catch (ConfigurationException e) {
257: disable("Cannot load tech stack configuration: " + e);
258: } catch (TransformerException e) {
259: disable("Cannot load tech stack configuration: " + e);
260: } catch (JselException e) {
261: context.warn(null,
262: "Cannot obtain external suppliers information: "
263: + e);
264: e.printStackTrace();
265: } catch (ParserConfigurationException e) {
266: context.warn(null, "Could not save tech stack to file: "
267: + e);
268: } catch (FactoryConfigurationError e) {
269: context.warn(null, "Could not save tech stack to file: "
270: + e);
271: }
272: }
273: }
|