0001: /*
0002: * Hammurapi
0003: * Automated Java code review system.
0004: * Copyright (C) 2004 Johannes Bellert
0005: *
0006: * This program is free software; you can redistribute it and/or modify
0007: * it under the terms of the GNU General Public License as published by
0008: * the Free Software Foundation; either version 2 of the License, or
0009: * (at your option) any later version.
0010: *
0011: * This program is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0014: * GNU General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU General Public License
0017: * along with this program; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0019: *
0020: * URL: http://www.pavelvlasov.com/pv/content/menu.show?id=products.jtaste
0021: * e-Mail: Johannes.Bellert@gmail.com
0022: */
0023: package org.hammurapi.inspectors.metrics;
0024:
0025: import java.io.FileInputStream;
0026: import java.io.FileOutputStream;
0027: import java.io.IOException;
0028: import java.io.InputStream;
0029: import java.math.BigDecimal;
0030: import java.net.URL;
0031: import java.util.Collection;
0032: import java.util.Enumeration;
0033: import java.util.HashSet;
0034: import java.util.Hashtable;
0035: import java.util.Iterator;
0036: import java.util.Properties;
0037: import java.util.Vector;
0038:
0039: import org.hammurapi.HammurapiException;
0040: import org.hammurapi.InspectorBase;
0041: import org.hammurapi.results.AnnotationContext;
0042: import org.hammurapi.results.LinkedAnnotation;
0043: import org.w3c.dom.Document;
0044: import org.w3c.dom.Element;
0045:
0046: import com.pavelvlasov.config.ConfigurationException;
0047: import com.pavelvlasov.config.Parameterizable;
0048: import com.pavelvlasov.jsel.Interface;
0049: import com.pavelvlasov.jsel.JselException;
0050: import com.pavelvlasov.jsel.Method;
0051: import com.pavelvlasov.jsel.Parameter;
0052: import com.pavelvlasov.jsel.Repository;
0053: import com.pavelvlasov.jsel.TypeBody;
0054: import com.pavelvlasov.jsel.TypeDefinition;
0055: import com.pavelvlasov.jsel.TypeSpecification;
0056: import com.pavelvlasov.jsel.VariableDefinition;
0057: import com.pavelvlasov.jsel.impl.ClassTypeSpecificationImpl;
0058: import com.pavelvlasov.render.RenderRequest;
0059: import com.pavelvlasov.render.RenderingException;
0060: import com.pavelvlasov.render.dom.AbstractRenderer;
0061: import com.pavelvlasov.review.SourceMarker;
0062:
0063: public class ArchitecturalLayerInspector extends InspectorBase
0064: implements ArchitecturalLayerConstants, Parameterizable {
0065:
0066: private static final String CONFIG_ERROR_MESSAGE = "'mapping-configuration-file', "
0067: + "'mapping-configuration-resource', and 'mapping-configuration-url' "
0068: + "parameters are mutually exclusive";
0069:
0070: private ArchitecturalLayerMappingTable architecturalLayerMappingTable = null;
0071: private ArchitecturalLayerExtensionsMap extensionMap = new ArchitecturalLayerExtensionsMap();
0072: private Hashtable allCategorizedPackages = new Hashtable();
0073: private Hashtable allCategorizedClasses = new Hashtable();
0074: private Hashtable allGetterSetterCounterForClasses = new Hashtable();
0075: private ListOfLayers listOfLayers = null;
0076: private Hashtable allTechStackEntitiesTable = new Hashtable();
0077: private ArchitecturalComplexityMappingTable complexityMappingTable = null;
0078: private HashSet unknownVariableList = new HashSet();
0079:
0080: private Coupling coupling = new Coupling();
0081: private CodeMetric projectMetric = new CodeMetric();
0082: String projectBaseDir = "";
0083: String xmlResourceName = this .getClass().getName()
0084: .replace('.', '/')
0085: + "XmlPretty.xsl";
0086: Repository repository = null;
0087:
0088: private String mappingConfigurationPath;
0089: private String mappingConfigurationResource;
0090: private String mappingConfigurationUrl;
0091:
0092: public void init() throws HammurapiException {
0093:
0094: try {
0095: InputStream inspectorStream;
0096: if (mappingConfigurationPath != null) {
0097: inspectorStream = new FileInputStream(
0098: this .mappingConfigurationPath);
0099: } else if (mappingConfigurationUrl != null) {
0100: inspectorStream = new URL(mappingConfigurationUrl)
0101: .openStream();
0102: } else if (mappingConfigurationResource != null) {
0103: inspectorStream = getClass().getClassLoader()
0104: .getResourceAsStream(
0105: mappingConfigurationResource);
0106: if (inspectorStream == null) {
0107: throw new HammurapiException("Resource not found: "
0108: + mappingConfigurationResource);
0109: }
0110: } else {
0111: String className = getClass().getName();
0112: int idx = className.lastIndexOf('.');
0113: String rName = (idx == -1 ? className : className
0114: .substring(idx + 1))
0115: + ".xml";
0116: inspectorStream = getClass().getResourceAsStream(rName);
0117: if (inspectorStream == null) {
0118: throw new HammurapiException(
0119: "Default mappig not found: " + rName);
0120: }
0121: }
0122:
0123: DomArchitecturalMappingSource source = new DomArchitecturalMappingSource(
0124: inspectorStream);
0125: this .architecturalLayerMappingTable = source
0126: .loadLayerMappings();
0127: this .complexityMappingTable = source
0128: .loadComplexityMapping();
0129: Enumeration enumAlm = architecturalLayerMappingTable
0130: .elements();
0131:
0132: while (enumAlm.hasMoreElements()) {
0133: ArchitecturalLayerMapping alm = (ArchitecturalLayerMapping) enumAlm
0134: .nextElement();
0135:
0136: Enumeration stackEnum = alm.getTechStackEntityList()
0137: .elements();
0138:
0139: while (stackEnum.hasMoreElements()) {
0140: TechStackEntity te = (TechStackEntity) stackEnum
0141: .nextElement();
0142: for (int i = 0; i < te.getExtensionMapping().size(); i++) {
0143: // System.out.println( (String)te.getExtensionMapping().elementAt(i) + " >-> "+ te.getName());
0144: this .extensionMap.put((String) te
0145: .getExtensionMapping().elementAt(i), te
0146: .getName());
0147: }
0148: }
0149: }
0150: Collection almList = architecturalLayerMappingTable
0151: .values();
0152: Iterator it = almList.iterator();
0153:
0154: while (it.hasNext()) {
0155: //for( int i=0; i<almList.size(); i++){
0156: // ArchitecturalLayerMapping alm = (ArchitecturalLayerMapping)architecturalLayerMappingTable.get((String)it.next());
0157: ArchitecturalLayerMapping alm = (ArchitecturalLayerMapping) it
0158: .next();
0159:
0160: // allTechStackEntitiesSet.addAll(alm.getTechStackEntityListValues());
0161: Collection clte = alm.getTechStackEntityListValues();
0162: Iterator itClte = clte.iterator();
0163: while (itClte.hasNext()) {
0164: TechStackEntity te = (TechStackEntity) itClte
0165: .next();
0166: allTechStackEntitiesTable.put(te.getName(), te);
0167: }
0168: }
0169:
0170: } catch (IOException e) {
0171: throw new HammurapiException(
0172: "Cannot load mapping configuration: " + e, e);
0173: }
0174: }
0175:
0176: public void visit(com.pavelvlasov.jsel.Package p) {
0177: if ("".equals(p.getName())) {
0178: allCategorizedPackages.put("<default>",
0179: new ListOfPackageCategories(p.getName()));
0180: } else {
0181: allCategorizedPackages.put(p.getName(),
0182: new ListOfPackageCategories(p.getName()));
0183:
0184: }
0185: }
0186:
0187: public void visit(TypeDefinition p) throws JselException,
0188: ClassNotFoundException {
0189:
0190: this .coupling.classCouplingMetric.put(p.getFcn(),
0191: new CouplingMetricOfClass(p));
0192: allCategorizedClasses.put(p.getFcn(), new ListOfCategories(p
0193: .getFcn(), ((SourceMarker) p).getSourceURL(),
0194: ((SourceMarker) p).getLine(), ((SourceMarker) p)
0195: .getColumn()));
0196: this .identifyCategories(p);
0197:
0198: }
0199:
0200: public void visit(Interface p) throws JselException,
0201: ClassNotFoundException {
0202: this .coupling.classCouplingMetric.put(p.getFcn(),
0203: new CouplingMetricOfClass(p));
0204: allCategorizedClasses.put(p.getFcn(), new ListOfCategories(p
0205: .getFcn(), ((SourceMarker) p).getSourceURL(),
0206: ((SourceMarker) p).getLine(), ((SourceMarker) p)
0207: .getColumn()));
0208: addCategory("Interface", p.getName(), p);
0209: }
0210:
0211: //!! job: read from XML descriptor
0212: public void checkExtentType(TypeDefinition type)
0213: throws JselException, ClassNotFoundException {
0214:
0215: Enumeration keys = extensionMap.keys();
0216: while (keys.hasMoreElements()) {
0217: String key = (String) keys.nextElement();
0218: String category = extensionMap.getProperty(key);
0219: checkExtendTypeHelper(key, category, type);
0220: }
0221: }
0222:
0223: //!! job: remember tokens which raise a ClassNotFounds and remove from list, for performance optimization
0224: private void checkExtendTypeHelper(String _loadClass,
0225: String category, TypeDefinition type) {
0226: try {
0227: if (type.isKindOf(_loadClass)) {
0228: addCategory(category, _loadClass, type);
0229: }
0230: } catch (JselException e) {
0231: // TODO Auto-generated catch block
0232: e.printStackTrace();
0233: }
0234: }
0235:
0236: /*
0237: *
0238: * Constant Identifier missing
0239: * 23public class Constants {
0240: 24 //~ Static fields/initializers ---------------------------------------------
0241: 25
0242: 26 public static final int PROCESS_STATUS_NOT_SUBMITTED = 1;
0243: 27 public static final int PROCESS_STATUS_OPEN = 2;
0244:
0245: *
0246: *
0247: */
0248: public void checkVariableType(TypeSpecification typDef,
0249: TypeDefinition declarationType) throws JselException,
0250: ClassNotFoundException {
0251: boolean foundAnyCategory = false;
0252: Iterator it = this .architecturalLayerMappingTable.values()
0253: .iterator();
0254:
0255: while (it.hasNext() && !foundAnyCategory) {
0256:
0257: ArchitecturalLayerMapping alm = (ArchitecturalLayerMapping) it
0258: .next();
0259: Iterator stackEnum = alm.getTechStackEntityListValues()
0260: .iterator();
0261: while (stackEnum.hasNext() && !foundAnyCategory) {
0262: TechStackEntity tse = (TechStackEntity) stackEnum
0263: .next();
0264: foundAnyCategory = iterateThroughVarDefSearchStrings(
0265: tse.getVariableMapping(), typDef,
0266: tse.getName(), declarationType);
0267: }
0268: }
0269: if (foundAnyCategory) {
0270: // I have a dam clue about this var
0271: } else {
0272: if (nonTrivialTypeFilter(typDef)) {
0273: unknownVariableList.add(typDef.getName());
0274: }
0275: }
0276:
0277: }
0278:
0279: public void checkVariableType(TypeSpecification typDef,
0280: TypeBody declarationType) throws JselException,
0281: ClassNotFoundException {
0282: boolean foundAnyCategory = false;
0283: Iterator it = this .architecturalLayerMappingTable.values()
0284: .iterator();
0285:
0286: while (it.hasNext() && !foundAnyCategory) {
0287:
0288: ArchitecturalLayerMapping alm = (ArchitecturalLayerMapping) it
0289: .next();
0290: Iterator stackEnum = alm.getTechStackEntityListValues()
0291: .iterator();
0292: while (stackEnum.hasNext() && !foundAnyCategory) {
0293: TechStackEntity tse = (TechStackEntity) stackEnum
0294: .next();
0295: foundAnyCategory = iterateThroughVarDefSearchStrings(
0296: tse.getVariableMapping(), typDef,
0297: tse.getName(), declarationType);
0298: }
0299: }
0300: if (foundAnyCategory) {
0301: // THIS means, I have a dam clue about this var
0302: } else {
0303: if (nonTrivialTypeFilter(typDef)) {
0304: unknownVariableList.add(typDef.getName());
0305: }
0306: }
0307:
0308: }
0309:
0310: public boolean iterateThroughVarDefSearchStrings(Vector searchList,
0311: TypeSpecification typeDef, String category,
0312: TypeDefinition declarationType) throws JselException {
0313:
0314: boolean foundAnyCategory = false;
0315: for (int i = 0; i < searchList.size(); i++) {
0316: String searchStr = (String) searchList.elementAt(i);
0317:
0318: if ("*".equals(searchStr.substring(searchStr.length() - 1))) {
0319: String packageStr = searchStr.substring(0, searchStr
0320: .length() - 1);
0321:
0322: if (typeDef.getName().startsWith(packageStr)) {
0323: addCategory(category, typeDef.getName(), typeDef,
0324: declarationType);
0325: foundAnyCategory = true;
0326: }
0327: } else if (searchStr.equals(typeDef.getName())) {
0328: addCategory(category, searchStr, typeDef,
0329: declarationType);
0330: foundAnyCategory = true;
0331: }
0332: }
0333: return foundAnyCategory;
0334: }
0335:
0336: public boolean iterateThroughVarDefSearchStrings(Vector searchList,
0337: TypeSpecification typeDef, String category,
0338: TypeBody declarationType) throws JselException {
0339:
0340: boolean foundAnyCategory = false;
0341:
0342: for (int i = 0; i < searchList.size(); i++) {
0343: String searchStr = (String) searchList.elementAt(i);
0344: if ("*".equals(searchStr.substring(searchStr.length() - 1))) {
0345: String packageStr = searchStr.substring(0, searchStr
0346: .length() - 1);
0347:
0348: if (typeDef.getName().startsWith(packageStr)) {
0349: addCategory(category, typeDef.getName(), typeDef,
0350: declarationType);
0351: foundAnyCategory = true;
0352: }
0353: } else if (searchStr.equals(typeDef.getName())) {
0354: addCategory(category, searchStr, typeDef,
0355: declarationType);
0356: foundAnyCategory = true;
0357: }
0358: }
0359: return foundAnyCategory;
0360: }
0361:
0362: public boolean nonTrivialTypeFilter(TypeSpecification typeDef)
0363: throws JselException {
0364: //!! should be xml configured
0365: if (typeDef.getName().startsWith("java.")
0366: || typeDef.getName().startsWith("com.ge.")
0367: || typeDef.getName().startsWith("ge.geia.")
0368: || typeDef.getName().startsWith("com.erc.")
0369: || typeDef.getName().startsWith("com.gefra.")
0370: || typeDef.getName().startsWith("com.geerc.")
0371: || typeDef.getName().startsWith("com.gecapital.")
0372: || typeDef.getName().startsWith("erc.")
0373: || typeDef.getName().startsWith("ercrio.rio.")
0374: || typeDef.getName().startsWith("com.iri.")
0375: || typeDef.getName().startsWith("com.igate.")) {
0376: return false;
0377: }
0378: return true;
0379: }
0380:
0381: public void visit(VariableDefinition variableDefinition) {
0382:
0383: // JDepend
0384: this .coupling.incrementVariableCoupling(variableDefinition);
0385:
0386: // Repository initialization
0387: if (repository == null) {
0388: repository = variableDefinition.getCompilationUnit()
0389: .getPackage().getRepository();
0390: }
0391: try {
0392: if (variableDefinition.getTypeSpecification() instanceof ClassTypeSpecificationImpl) {
0393: try {
0394:
0395: TypeDefinition typeDef = variableDefinition
0396: .getRootEnclosingType();
0397: checkVariableType(variableDefinition
0398: .getTypeSpecification(), typeDef);
0399: } catch (JselException e) {
0400: context.warn(variableDefinition, e);
0401: }
0402: } else {
0403: // System.out.println( " OO " + variableDefinition.getTypeSpecification().getClass().toString() );
0404: }
0405: } catch (ClassNotFoundException e) {
0406: context.warn(variableDefinition, e);
0407: }
0408: }
0409:
0410: public void visit(Parameter parameter) {
0411:
0412: // JDepend
0413: this .coupling.incrementVariableCoupling(parameter);
0414:
0415: if (repository == null) {
0416: repository = parameter.getCompilationUnit().getPackage()
0417: .getRepository();
0418: }
0419:
0420: try {
0421: if (parameter.getTypeSpecification() instanceof ClassTypeSpecificationImpl) {
0422: try {
0423: TypeSpecification ts = parameter
0424: .getTypeSpecification();
0425: checkVariableType(ts, parameter.getParent()
0426: .getEnclosingType());
0427: } catch (JselException e) {
0428: context.warn(parameter, e);
0429: }
0430: }
0431: } catch (ClassNotFoundException e) {
0432: context.warn(parameter, e);
0433: }
0434:
0435: }
0436:
0437: /*
0438: public void addCategory(String category, String variableIdent, VariableDefinition element, TypeDefinition declarationType) {
0439: ListOfCategories typeLoc = null;
0440: typeLoc = (ListOfCategories) allCategorizedClasses.get(element.getEnclosingType().getFcn());
0441: typeLoc.add(new ArchitecturalCategory(
0442: ((SourceMarker)element).getSourceURL(),
0443: ((SourceMarker)element).getLine(),
0444: ((SourceMarker)element).getColumn(),
0445: variableIdent, category));
0446: }
0447: */
0448: /*
0449: public void addCategory(String category, String variableIdent, VariableDefinition element, TypeBody declarationType) {
0450: ListOfCategories typeLoc = null;
0451: typeLoc = (ListOfCategories) allCategorizedClasses.get(element.getEnclosingType().getFcn());
0452: typeLoc.add(new ArchitecturalCategory(
0453: ((SourceMarker)element).getSourceURL(),
0454: ((SourceMarker)element).getLine(),
0455: ((SourceMarker)element).getColumn(),
0456: variableIdent, category));
0457: }
0458: */
0459: /*
0460: public void addCategory(String category, String variableIdent, Interface element, TypeDefinition declarationType) {
0461: ListOfCategories typeLoc = null;
0462: typeLoc = (ListOfCategories) allCategorizedClasses.get(element.getFcn());
0463: typeLoc.add(new ArchitecturalCategory(
0464: ((SourceMarker)element).getSourceURL(),
0465: ((SourceMarker)element).getLine(),
0466: ((SourceMarker)element).getColumn(),
0467: variableIdent, category));
0468: }
0469: */
0470: public void addCategory(String category, String variableIdent,
0471: TypeSpecification element, TypeDefinition declarationType)
0472: throws JselException {
0473: ListOfCategories typeLoc = null;
0474: if (declarationType != null) {
0475: typeLoc = (ListOfCategories) allCategorizedClasses
0476: .get(declarationType.getFcn());
0477:
0478: //!! job: what happens with missing categories??
0479: if (typeLoc == null) {
0480: // typeLoc = new ListOfCategories( declarationType.getFcn( );
0481: // allCategorizedClasses.put( declarationType.getFcn(), typeLoc );
0482: new Exception().printStackTrace();
0483: } else {
0484: typeLoc.add(new ArchitecturalCategory(
0485: ((SourceMarker) element).getSourceURL(),
0486: ((SourceMarker) element).getLine(),
0487: ((SourceMarker) element).getColumn(),
0488: variableIdent, category));
0489: }
0490: }
0491: }
0492:
0493: public void addCategory(String category, String variableIdent,
0494: TypeSpecification element, TypeBody declarationType)
0495: throws JselException {
0496:
0497: ListOfCategories typeLoc = null;
0498:
0499: if (declarationType != null) {
0500: typeLoc = (ListOfCategories) allCategorizedClasses
0501: .get(declarationType.getFcn());
0502:
0503: //!! job: what happens with missing categories??
0504: if (typeLoc == null) {
0505: // typeLoc = new ListOfCategories( declarationType.getFcn( );
0506: // allCategorizedClasses.put( declarationType.getFcn(), typeLoc );
0507: } else {
0508:
0509: //!! put in here (and all category constructors a complexity helper method
0510: typeLoc.add(new ArchitecturalCategory(
0511: ((SourceMarker) element).getSourceURL(),
0512: ((SourceMarker) element).getLine(),
0513: ((SourceMarker) element).getColumn(),
0514: variableIdent, category));
0515: }
0516: }
0517: }
0518:
0519: public void addCategory(String category, String variableIdent,
0520: TypeDefinition element) throws JselException {
0521: ListOfCategories typeLoc = null;
0522: typeLoc = (ListOfCategories) allCategorizedClasses.get(element
0523: .getFcn());
0524:
0525: typeLoc.add(new ArchitecturalCategory(((SourceMarker) element)
0526: .getSourceURL(), ((SourceMarker) element).getLine(),
0527: ((SourceMarker) element).getColumn(), variableIdent,
0528: category));
0529: }
0530:
0531: /*
0532: public void addCategory(ListOfCategories typeLoc, String category, String variableIdent, LanguageElement element) {
0533: try {
0534: typeLoc.add(new ArchitecturalCategory(
0535: ((SourceMarker)element).getSourceURL(),
0536: ((SourceMarker)element).getLine(),
0537: ((SourceMarker)element).getColumn(),
0538: variableIdent, category));
0539: } catch (Exception e) {
0540: context.warn(element, e);
0541: }
0542: }
0543: */
0544: public void addCategory(ListOfCategories typeLoc, String category,
0545: String variableIdent, String fcn) {
0546: typeLoc.add(new ArchitecturalCategory(fcn, 0, 0, variableIdent,
0547: category));
0548: }
0549:
0550: public void visit(Method p) {
0551: //!! detect Connection >> prepareCall( )
0552:
0553: int start = p.getAst().getFirstToken().getLine();
0554: int end = p.getAst().getLastToken().getLine();
0555: TypeBody enclosingType = p.getEnclosingType();
0556: final String fcn = enclosingType.getFcn();
0557:
0558: if (((end - start) < 3)
0559: && (p.getName().toString().startsWith("get") || p
0560: .getName().toString().startsWith("set"))) {
0561: try {
0562: String keyGetterSetter = fcn + GETTERSETTER;
0563: Integer getterCounter = (Integer) allGetterSetterCounterForClasses
0564: .get(keyGetterSetter);
0565: if (getterCounter == null) {
0566: allGetterSetterCounterForClasses.put(
0567: keyGetterSetter, new Integer(1));
0568: ListOfCategories typeLoc = (ListOfCategories) allCategorizedClasses
0569: .get(fcn);
0570: if (typeLoc != null) {
0571: typeLoc.setType(fcn);
0572: }
0573: } else {
0574: allGetterSetterCounterForClasses.put(
0575: keyGetterSetter, new Integer(getterCounter
0576: .intValue() + 1));
0577: }
0578: } catch (Exception e) {
0579: e.printStackTrace();
0580: }
0581:
0582: } else {
0583: try {
0584: Integer getterCounter = (Integer) allGetterSetterCounterForClasses
0585: .get(fcn);
0586: if (getterCounter == null) {
0587: allGetterSetterCounterForClasses.put(fcn,
0588: new Integer(1));
0589: ListOfCategories typeLoc = (ListOfCategories) allCategorizedClasses
0590: .get(fcn);
0591: if (typeLoc != null) {
0592: typeLoc.setType(fcn);
0593: }
0594: } else {
0595: allGetterSetterCounterForClasses.put(fcn,
0596: new Integer(getterCounter.intValue() + 1));
0597: }
0598: } catch (Exception e) {
0599: e.printStackTrace();
0600: }
0601: }
0602: }
0603:
0604: public void identifyCategories(TypeDefinition c)
0605: throws JselException, ClassNotFoundException {
0606: this .checkExtentType(c);
0607: return;
0608: }
0609:
0610: public void aggregate() {
0611: // create Getter-Setter Categories
0612: checkGetterSetter();
0613:
0614: //-- compress to package level
0615: compressClassesToPackageLevel();
0616:
0617: determineLayerPerPackage();
0618: extractLayer2PackageRelations();
0619: }
0620:
0621: private void extractLayer2PackageRelations() {
0622: listOfLayers = new ListOfLayers(this .allCategorizedPackages);
0623: }
0624:
0625: private void compressClassesToPackageLevel() {
0626:
0627: Enumeration classesEnum = this .allCategorizedClasses.keys();
0628: while (classesEnum.hasMoreElements()) {
0629: String key = (String) classesEnum.nextElement();
0630: ListOfCategories loc = (ListOfCategories) allCategorizedClasses
0631: .get(key);
0632:
0633: ListOfPackageCategories lopc = (ListOfPackageCategories) this .allCategorizedPackages
0634: .get(ListOfPackageCategories.getWithClassFcn(key));
0635:
0636: if (loc.size() == 0) {
0637: ArchitecturalCategoryPackage pnac = (ArchitecturalCategoryPackage) lopc
0638: .get("NOT CATEGORIZED");
0639: if (pnac != null) {
0640: pnac.occurance++;
0641: } else {
0642: // logger.error(" No ArchitecturalCategory for <NOT CATEGORIZED> initialized. ");
0643: }
0644: }
0645:
0646: for (int i = 0; i < loc.size(); i++) {
0647: try {
0648: ArchitecturalCategory ac = (ArchitecturalCategory) loc
0649: .elementAt(i);
0650: // System.out.println ("*** " +ac.categoryType );
0651: ArchitecturalCategoryPackage pac = lopc
0652: .get(ac.categoryType);
0653: if (pac == null) {
0654: lopc
0655: .put(
0656: ac.categoryType,
0657: new ArchitecturalCategoryPackage(
0658: key, ac.categoryType,
0659: ac.source_url));
0660: } else {
0661: pac.occurance++;
0662: }
0663: } catch (RuntimeException e) {
0664: // TODO Auto-generated catch block
0665: }
0666: }
0667: }
0668: }
0669:
0670: private void checkGetterSetter() {
0671: //!!
0672: double ratio = 0;
0673: Enumeration propertyEnum = allGetterSetterCounterForClasses
0674: .keys();
0675: while (propertyEnum.hasMoreElements()) {
0676: String key = (String) propertyEnum.nextElement();
0677: Integer numGetterSetter = (Integer) allGetterSetterCounterForClasses
0678: .get(key + GETTERSETTER);
0679: Integer num = (Integer) allGetterSetterCounterForClasses
0680: .get(key);
0681: if (numGetterSetter != null && num != null) {
0682: ratio = new Double(num.intValue()).doubleValue()
0683: / new Double(numGetterSetter.intValue())
0684: .doubleValue();
0685: } else if (numGetterSetter != null && num == null) {
0686: ratio = -1;
0687: } else if (numGetterSetter == null && num != null) {
0688: ratio = 1;
0689: }
0690: //System.out.println( "§§ " + num +" / "+ numGetterSetter + " = "+ ratio );
0691: if (ratio < 0.3) {
0692: ListOfCategories typeLoc = (ListOfCategories) allCategorizedClasses
0693: .get(key);
0694: if (typeLoc != null) {
0695: BigDecimal bg = new BigDecimal(ratio);
0696: addCategory(
0697: typeLoc,
0698: VALUE_OBJECT,
0699: "Getter/Setter Count = "
0700: + numGetterSetter
0701: + " Ratio: "
0702: + bg
0703: .divide(
0704: new BigDecimal(
0705: "1.0"),
0706: 2,
0707: BigDecimal.ROUND_HALF_UP)
0708: .toString(), typeLoc
0709: .getSourceURL());
0710: }
0711: }
0712: }
0713: }
0714:
0715: private void determineLayerPerPackage() {
0716:
0717: Enumeration enumKey = this .allCategorizedPackages.keys();
0718: while (enumKey.hasMoreElements()) {
0719: String key = (String) enumKey.nextElement();
0720: ListOfPackageCategories loc = (ListOfPackageCategories) this .allCategorizedPackages
0721: .get(key);
0722: loc.setLayers(this .determineLayerInListOfCategories(loc));
0723: }
0724:
0725: return;
0726: }
0727:
0728: private HashSet determineLayerInListOfCategories(
0729: ListOfPackageCategories loc) {
0730: HashSet layers = new HashSet();
0731: // Enumeration keys = architecturalLayerMapping.getMappings().keys();
0732: Enumeration keys = architecturalLayerMappingTable.keys();
0733:
0734: while (keys.hasMoreElements()) {
0735: String layer = (String) keys.nextElement();
0736: // System.out.print ( "layer " + layer );
0737: ArchitecturalLayerMapping alMapping = architecturalLayerMappingTable
0738: .get(layer);
0739: Iterator itAlTe = alMapping.getTechStackEntityListValues()
0740: .iterator();
0741: while (itAlTe.hasNext()) {
0742:
0743: TechStackEntity tse = (TechStackEntity) itAlTe.next();
0744:
0745: if (loc.contains(tse.getName())) {
0746: // layers.add((String) architecturalLayerMapping.getMappings().get(key));
0747: layers.add(layer);
0748:
0749: // layers.add((String) architecturalLayerMappingTable.get(key));
0750: // System.out.println ( " ..added" );
0751: } else {
0752: // System.out.println ( " ..failed" );
0753: }
0754: }
0755: }
0756: return layers;
0757: }
0758:
0759: public void leave(Repository repository) {
0760: aggregate();
0761:
0762: context.annotate(new LinkedAnnotation() {
0763: private String path;
0764:
0765: public String getName() {
0766: return getContext().getDescriptor().getName();
0767: }
0768:
0769: public String getPath() {
0770: return path;
0771: }
0772:
0773: public Properties getProperties() {
0774: Properties ret = new Properties();
0775: ret.setProperty("left-panel", "yes");
0776: ret.setProperty("target", "Architectual Layers");
0777: return ret;
0778: }
0779:
0780: public void render(AnnotationContext context)
0781: throws HammurapiException {
0782: String errorCausingFile = "";
0783: projectMetric.setName("Project");
0784: projectMetric.setDescriptonEntity(projectMetric
0785: .getName());
0786:
0787: // Output images here. See AnnotationTest for details.
0788:
0789: class ArchitecturalLayerInspectorRenderer extends
0790: AbstractRenderer {
0791:
0792: ArchitecturalLayerInspectorRenderer() {
0793:
0794: super (new RenderRequest(
0795: ArchitecturalLayerInspector.this ));
0796: }
0797:
0798: public Element render(Document document)
0799: throws RenderingException {
0800: HashSet hs = new HashSet();
0801:
0802: ArchitecturalLayerInspector myInspector = (ArchitecturalLayerInspector) request
0803: .getRenderee();
0804: ;
0805: Element entities = document
0806: .createElement("Entities");
0807: Element inspectorElement = document
0808: .createElement("ArchitecturalLayers");
0809:
0810: Enumeration enumC = allCategorizedClasses
0811: .elements();
0812: while (enumC.hasMoreElements()) {
0813: ListOfCategories loc = (ListOfCategories) enumC
0814: .nextElement();
0815: inspectorElement.appendChild(loc
0816: .toDom(document));
0817: for (int i = 0; i < loc.size(); i++) {
0818: hs.add(((ArchitecturalCategory) loc
0819: .get(i)).categoryType);
0820: }
0821: }
0822:
0823: Element tsel = document
0824: .createElement("TechStackEntityList");
0825: inspectorElement.appendChild(tsel);
0826:
0827: Collection almList = architecturalLayerMappingTable
0828: .values();
0829: Iterator it = almList.iterator();
0830:
0831: while (it.hasNext()) {
0832: ArchitecturalLayerMapping alm = (ArchitecturalLayerMapping) it
0833: .next();
0834:
0835: Collection clte = alm
0836: .getTechStackEntityListValues();
0837: Iterator itClte = clte.iterator();
0838: tsel.appendChild(alm.toDom(document));
0839: }
0840: Element tselU = document
0841: .createElement("UsedTechStackEntityList");
0842: inspectorElement.appendChild(tselU);
0843:
0844: Vector usedTechStackEntityList = new Vector();
0845: Iterator itHs = hs.iterator();
0846: while (itHs.hasNext()) {
0847: TechStackEntity tse = (TechStackEntity) allTechStackEntitiesTable
0848: .get((String) itHs.next());
0849: if (tse != null) {
0850: tselU.appendChild(tse.toDom(document));
0851: usedTechStackEntityList.add(tse);
0852: }
0853: }
0854: //!! markUsedJarFiles
0855: JarFileList jarFileList = new JarFileLookup()
0856: .parseClasspath();
0857: jarFileList.markUsedJarFiles(
0858: usedTechStackEntityList,
0859: allTechStackEntitiesTable);
0860: inspectorElement.appendChild(jarFileList
0861: .toDom(document));
0862:
0863: //-------------------------------------------------------------------------
0864:
0865: Element projSumE = document
0866: .createElement("ProjectSummary");
0867: projSumE.setAttribute("number", String
0868: .valueOf(""));
0869: inspectorElement.appendChild(projSumE);
0870: inspectorElement.appendChild(listOfLayers
0871: .toDom(document));
0872: Enumeration enump = allCategorizedPackages
0873: .elements();
0874: while (enump.hasMoreElements()) {
0875: ListOfPackageCategories loc = (ListOfPackageCategories) enump
0876: .nextElement();
0877: inspectorElement.appendChild(loc
0878: .toDom(document));
0879: }
0880: Element tselr = document
0881: .createElement("TechStackEntityRating");
0882: inspectorElement.appendChild(tselr);
0883: Enumeration enumalmt = architecturalLayerMappingTable
0884: .elements();
0885: while (enumalmt.hasMoreElements()) {
0886: ArchitecturalLayerMapping almx = (ArchitecturalLayerMapping) enumalmt
0887: .nextElement();
0888: Enumeration enumte = almx
0889: .getTechStackEntityList()
0890: .elements();
0891: while (enumte.hasMoreElements()) {
0892: TechStackEntity tse = (TechStackEntity) enumte
0893: .nextElement();
0894: tselr.appendChild(tse.toDom(document));
0895: }
0896: }
0897: inspectorElement
0898: .appendChild(new ArchitecturalLayerMapping()
0899: .toDom(document));
0900: inspectorElement.appendChild(extensionMap
0901: .toDom(document));
0902: inspectorElement
0903: .appendChild(complexityMappingTable
0904: .toDom(document));
0905:
0906: Element urantvlst = document
0907: .createElement("UnResolvedAndNonTrivialVariableList");
0908: Iterator ituvl = unknownVariableList.iterator();
0909: while (ituvl.hasNext()) {
0910: Element urantv = document
0911: .createElement("UnResolvedAndNonTrivialVariable");
0912: urantv.setAttribute("name", (String) ituvl
0913: .next());
0914: urantvlst.appendChild(urantv);
0915: }
0916: inspectorElement.appendChild(urantvlst);
0917: inspectorElement.appendChild(coupling
0918: .toDom(document));
0919: return inspectorElement;
0920: }
0921: } //-- end class Renderer
0922:
0923: AnnotationContext.FileEntry fileEntry = context
0924: .getNextFile(context.getExtension());
0925: path = fileEntry.getPath();
0926: AnnotationContext.FileEntry fileEntryXml = context
0927: .getNextFile(".xml");
0928: try {
0929: ArchitecturalLayerInspectorRenderer renderer = new ArchitecturalLayerInspectorRenderer();
0930: FileOutputStream out = new FileOutputStream(
0931: fileEntry.getFile());
0932:
0933: renderer
0934: .setEmbeddedStyle(context.isEmbeddedStyle());
0935: try {
0936: errorCausingFile = fileEntry.getFile()
0937: .getAbsolutePath();
0938: renderer
0939: .render(
0940: context.getParameter("style") == null ? null
0941: : new FileInputStream(
0942: context
0943: .getParameter(
0944: "style")
0945: .toString()),
0946: out);
0947:
0948: } finally {
0949: out.close();
0950: }
0951: FileOutputStream outXml = new FileOutputStream(
0952: fileEntryXml.getFile());
0953: try {
0954: errorCausingFile = fileEntryXml.getFile()
0955: .getAbsolutePath();
0956: //-- write a XML file for other XSL usage
0957: renderer.setEmbeddedStyle(false);
0958: renderer.render(outXml);
0959: // renderer.setPrettyPrint( true );
0960: // InputStream inStream=getClass().getClassLoader().getResourceAsStream(xmlResourceName);
0961: // renderer.render(inStream, outXml);
0962:
0963: } finally {
0964: outXml.close();
0965: }
0966: } catch (Exception e) {
0967: throw new HammurapiException("Can't save "
0968: + errorCausingFile + ". " + e.getMessage());
0969: }
0970: }
0971: });
0972:
0973: }
0974:
0975: /**
0976: * Configures the rule. Reads in the values of the parameters XXX and
0977: * class-max-complexity.
0978: *
0979: * @param name the name of the parameter being loaded from Hammurapi configuration
0980: * @param value the value of the parameter being loaded from Hammurapi configuration
0981: * @exception ConfigurationException in case of a not supported parameter
0982: */
0983: public boolean setParameter(String name, Object value)
0984: throws ConfigurationException {
0985:
0986: if ("mapping-configuration-file".equals(name)) {
0987: if (mappingConfigurationResource != null) {
0988: throw new ConfigurationException(CONFIG_ERROR_MESSAGE);
0989: }
0990: if (mappingConfigurationUrl != null) {
0991: throw new ConfigurationException(CONFIG_ERROR_MESSAGE);
0992: }
0993: mappingConfigurationPath = value.toString();
0994: } else if ("mapping-configuration-resource".equals(name)) {
0995: if (mappingConfigurationPath != null) {
0996: throw new ConfigurationException(CONFIG_ERROR_MESSAGE);
0997: }
0998: if (mappingConfigurationUrl != null) {
0999: throw new ConfigurationException(CONFIG_ERROR_MESSAGE);
1000: }
1001: mappingConfigurationResource = value.toString();
1002: } else if ("mapping-configuration-url".equals(name)) {
1003: if (mappingConfigurationPath != null) {
1004: throw new ConfigurationException(CONFIG_ERROR_MESSAGE);
1005: }
1006: if (mappingConfigurationResource != null) {
1007: throw new ConfigurationException(CONFIG_ERROR_MESSAGE);
1008: }
1009: mappingConfigurationUrl = value.toString();
1010: } else {
1011: throw new ConfigurationException("Parameter '" + name
1012: + "' is not supported");
1013: }
1014: return true;
1015: }
1016:
1017: }
|