View Javadoc

1   // $Id: SimilarTypeFinderWorker.java 165 2009-05-28 21:46:38Z agony $
2   /*
3    * xsAnalyzer - XML schema analyzing tool. Copyright (C) 2008 Michael Engelhardt
4    * 
5    * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
6    * License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
7    * version.
8    * 
9    * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
10   * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11   * 
12   * You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
13   * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14   */
15  /**
16   * 
17   */
18  package de.mindcrimeilab.xsanalyzer;
19  
20  import java.security.NoSuchAlgorithmException;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import org.apache.xerces.impl.xs.util.XSObjectListImpl;
28  import org.apache.xerces.xs.XSConstants;
29  import org.apache.xerces.xs.XSObject;
30  import org.apache.xerces.xs.XSObjectList;
31  import org.apache.xerces.xs.XSTypeDefinition;
32  
33  import de.mindcrimeilab.xsanalyzer.util.XSModelHelper;
34  import de.mindcrimeilab.xsanalyzer.xsext.TypeDescriptionFactory;
35  
36  /**
37   * @author Michael Engelhardt<me@mindcrime-ilab.de>
38   * @author $Author: agony $
39   * @version $Revision: 165 $
40   * 
41   */
42  public class SimilarTypeFinderWorker extends NamespaceFilteredWorker implements XsComponentWorker {
43  
44      private final Map<String, XSObjectListImpl> similarTypes;
45  
46      private final TypeDescriptionFactory factory;
47  
48      public SimilarTypeFinderWorker() {
49          super();
50          similarTypes = new HashMap<String, XSObjectListImpl>();
51          try {
52  
53              factory = new TypeDescriptionFactory();
54          }
55          catch (NoSuchAlgorithmException e) {
56              SimilarTypeFinderWorker.logger.error("SimilarTypeFinder()", e);
57              throw new RuntimeException("Cannot create " + TypeDescriptionFactory.class.getName());
58          }
59      }
60  
61      public synchronized Map<String, ? extends XSObjectList> getSimilarTypes() {
62          removeSingularTypes();
63          return Collections.unmodifiableMap(similarTypes);
64      }
65  
66      /*
67       * (non-Javadoc)
68       * 
69       * @see de.mindcrimeilab.xsanalyzer.XsComponentWorker#execute(org.apache.xerces.xs.XSObject,
70       * org.apache.xerces.xs.XSObject)
71       */
72      @Override
73      public void execute(XSObject object, XSObject parent) {
74          final XSTypeDefinition stype = (XSTypeDefinition) object;
75          String signature = generateTypeSignature(stype);
76          addSimilarType(signature, stype);
77      }
78  
79      /*
80       * (non-Javadoc)
81       * 
82       * @see de.mindcrimeilab.xsanalyzer.XsComponentWorker#isSupported(org.apache.xerces.xs.XSObject)
83       */
84      @Override
85      public boolean isSupported(XSObject object) {
86          final boolean result;
87          if (object.getType() == XSConstants.TYPE_DEFINITION) {
88              if (((XSTypeDefinition) object).getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
89                  result = super.isSupported(object);
90              }
91              else if (((XSTypeDefinition) object).getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
92                  result = super.isSupported(object);
93              }
94              else {
95                  result = false;
96              }
97          }
98          else {
99              result = false;
100         }
101         return result;
102     }
103 
104     /**
105      * 
106      * @param type
107      * @return
108      */
109     private String generateTypeSignature(XSTypeDefinition type) {
110         return factory.generateTypeDescriptionSignature(type);
111     }
112 
113     private void addSimilarType(String signatureDigest, XSTypeDefinition type) {
114         // do not add null ;)
115         final XSObjectListImpl xsoList;
116         if (similarTypes.containsKey(signatureDigest)) {
117             xsoList = similarTypes.get(signatureDigest);
118             for (int i = 0; i < xsoList.getLength(); ++i) {
119                 XSObject object = xsoList.item(i);
120                 // check for duplicate types
121                 if (XSModelHelper.isSameTypeDefinition(object, type)) { return; }
122             }
123             xsoList.add(type);
124         }
125         else {
126             xsoList = new XSObjectListImpl();
127             xsoList.add(type);
128             similarTypes.put(signatureDigest, xsoList);
129         }
130     }
131 
132     private void removeSingularTypes() {
133         Set<String> keys = similarTypes.keySet();
134         for (Iterator<String> it = keys.iterator(); it.hasNext();) {
135             String key = it.next();
136             if (similarTypes.get(key).getLength() < 2) {
137                 SimilarTypeFinderWorker.logger.debug("Removing key [" + key + "] having count < 2");
138                 it.remove();
139             }
140         }
141     }
142 
143 }