View Javadoc
1   // $Id: SameNameDifferentTypeFinderWorker.java 164 2009-05-27 18:08:13Z 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.lang.reflect.Method;
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 javax.xml.namespace.QName;
28  
29  import org.apache.xerces.impl.xs.util.XSObjectListImpl;
30  import org.apache.xerces.xs.XSConstants;
31  import org.apache.xerces.xs.XSObject;
32  import org.apache.xerces.xs.XSObjectList;
33  import org.apache.xerces.xs.XSTypeDefinition;
34  
35  import de.mindcrimeilab.xsanalyzer.util.XSModelHelper;
36  
37  /**
38   * 
39   * @author Michael Engelhardt<me@mindcrime-ilab.de>
40   * @author $Author: agony $
41   * @version $Revision: 164 $
42   * 
43   */
44  public class SameNameDifferentTypeFinderWorker extends NamespaceFilteredWorker implements XsComponentWorker {
45  
46      private final Map<QName, XSObjectListImpl> typesWithSameName;
47  
48      /**
49       * 
50       */
51      public SameNameDifferentTypeFinderWorker() {
52          super();
53          typesWithSameName = new HashMap<QName, XSObjectListImpl>();
54      }
55  
56      /**
57       * @return the typesWithSameName
58       */
59      public synchronized Map<QName, ? extends XSObjectList> getTypesWithSameName() {
60          removeSingularTypes();
61          return Collections.unmodifiableMap(typesWithSameName);
62      }
63  
64      /*
65       * (non-Javadoc)
66       * 
67       * @see de.mindcrimeilab.xsanalyzer.XsComponentWorker#execute(org.apache.xerces.xs.XSObject,
68       * org.apache.xerces.xs.XSObject)
69       */
70      @Override
71      public void execute(XSObject object, XSObject parent) {
72          try {
73              Method m = object.getClass().getMethod("getTypeDefinition", new Class[] {});
74              XSTypeDefinition typedef = (XSTypeDefinition) m.invoke(object, new Object[] {});
75              this.addTypeWithSameName(new QName(object.getNamespace(), object.getName()), typedef);
76          }
77          catch (Exception e) {
78              logger.error("Cannot invoke method getTypeDefinition() on " + object + ".", e);
79          }
80      }
81  
82      /*
83       * (non-Javadoc)
84       * 
85       * @see de.mindcrimeilab.xsanalyzer.XsComponentWorker#isSupported(org.apache.xerces.xs.XSObject)
86       */
87      @Override
88      public boolean isSupported(XSObject object) {
89          return object.getType() == XSConstants.ELEMENT_DECLARATION || object.getType() == XSConstants.ATTRIBUTE_DECLARATION;
90      }
91  
92      private void addTypeWithSameName(QName qname, XSTypeDefinition type) {
93          // do not add null ;)
94          final XSObjectListImpl xsoList;
95          if (typesWithSameName.containsKey(qname)) {
96              xsoList = typesWithSameName.get(qname);
97              for (int i = 0; i < xsoList.getLength(); ++i) {
98                  XSObject object = xsoList.item(i);
99                  // check for duplicate types
100                 if (XSModelHelper.isSameTypeDefinition(object, type)) { return; }
101             }
102             xsoList.add(type);
103         }
104         else {
105             xsoList = new XSObjectListImpl();
106             xsoList.add(type);
107             typesWithSameName.put(qname, xsoList);
108         }
109     }
110 
111     private void removeSingularTypes() {
112         Set<QName> keys = typesWithSameName.keySet();
113         for (Iterator<QName> it = keys.iterator(); it.hasNext();) {
114             QName key = it.next();
115             if (typesWithSameName.get(key).getLength() < 2) {
116                 logger.debug("Removing key [" + key + "] having count < 2");
117                 it.remove();
118             }
119         }
120     }
121 
122 }