001    package nl.tudelft.tbm.eeni.owl2java.model.xsd;
002    
003    import nl.tudelft.tbm.eeni.owl2java.utils.GraphPathUtils;
004    import org.jgraph.graph.DefaultEdge;
005    import org.jgrapht.DirectedGraph;
006    import org.jgrapht.GraphPath;
007    import org.jgrapht.alg.DijkstraShortestPath;
008    import org.jgrapht.graph.DefaultDirectedGraph;
009    
010    import java.util.ArrayList;
011    import java.util.List;
012    
013    public class XsdGraph {
014    
015        private static final DirectedGraph<String, DefaultEdge> xsdGraph = new DefaultDirectedGraph<String, DefaultEdge>(
016                DefaultEdge.class);
017    
018        static {
019            // add vertexes
020            xsdGraph.addVertex(XsdSchema.xsdENTITY);
021            xsdGraph.addVertex(XsdSchema.xsdID);
022            xsdGraph.addVertex(XsdSchema.xsdIDREF);
023            xsdGraph.addVertex(XsdSchema.xsdNCName);
024            xsdGraph.addVertex(XsdSchema.xsdNMTOKEN);
025            xsdGraph.addVertex(XsdSchema.xsdNOTATION);
026            xsdGraph.addVertex(XsdSchema.xsdName);
027            xsdGraph.addVertex(XsdSchema.xsdQName);
028            xsdGraph.addVertex(XsdSchema.xsdanyURI);
029            xsdGraph.addVertex(XsdSchema.xsdbase64Binary);
030            xsdGraph.addVertex(XsdSchema.xsdboolean);
031            xsdGraph.addVertex(XsdSchema.xsdbyte);
032            xsdGraph.addVertex(XsdSchema.xsddate);
033            xsdGraph.addVertex(XsdSchema.xsddateTime);
034            xsdGraph.addVertex(XsdSchema.xsddecimal);
035            xsdGraph.addVertex(XsdSchema.xsddouble);
036            xsdGraph.addVertex(XsdSchema.xsdduration);
037            xsdGraph.addVertex(XsdSchema.xsdfloat);
038            xsdGraph.addVertex(XsdSchema.xsdgDay);
039            xsdGraph.addVertex(XsdSchema.xsdgMonth);
040            xsdGraph.addVertex(XsdSchema.xsdgMonthDay);
041            xsdGraph.addVertex(XsdSchema.xsdgYear);
042            xsdGraph.addVertex(XsdSchema.xsdgYearMonth);
043            xsdGraph.addVertex(XsdSchema.xsdhexBinary);
044            xsdGraph.addVertex(XsdSchema.xsdint);
045            xsdGraph.addVertex(XsdSchema.xsdinteger);
046            xsdGraph.addVertex(XsdSchema.xsdlanguage);
047            xsdGraph.addVertex(XsdSchema.xsdlong);
048            xsdGraph.addVertex(XsdSchema.xsdnegativeInteger);
049            xsdGraph.addVertex(XsdSchema.xsdnonNegativeInteger);
050            xsdGraph.addVertex(XsdSchema.xsdnonPositiveInteger);
051            xsdGraph.addVertex(XsdSchema.xsdnormalizedString);
052            xsdGraph.addVertex(XsdSchema.xsdpositiveInteger);
053            xsdGraph.addVertex(XsdSchema.xsdshort);
054            xsdGraph.addVertex(XsdSchema.xsdstring);
055            xsdGraph.addVertex(XsdSchema.xsdtime);
056            xsdGraph.addVertex(XsdSchema.xsdtoken);
057            xsdGraph.addVertex(XsdSchema.xsdunsignedByte);
058            xsdGraph.addVertex(XsdSchema.xsdunsignedInt);
059            xsdGraph.addVertex(XsdSchema.xsdunsignedLong);
060            xsdGraph.addVertex(XsdSchema.xsdunsignedShort);
061            xsdGraph.addVertex(XsdSchema.xsdLiteral);
062    
063            // add edges -> first level
064            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdduration);
065            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsddateTime);
066            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdtime);
067            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsddate);
068            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdgYearMonth);
069            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdgYear);
070            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdgMonthDay);
071            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdgDay);
072            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdgMonth);
073            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdboolean);
074            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdbase64Binary);
075            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdhexBinary);
076            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdfloat);
077            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsddouble);
078            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdanyURI);
079            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdQName);
080            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdNOTATION);
081            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsdstring);
082            xsdGraph.addEdge(XsdSchema.xsdLiteral, XsdSchema.xsddecimal);
083    
084            // sub elements of string
085            xsdGraph.addEdge(XsdSchema.xsdstring, XsdSchema.xsdnormalizedString);
086            xsdGraph.addEdge(XsdSchema.xsdnormalizedString, XsdSchema.xsdtoken);
087            xsdGraph.addEdge(XsdSchema.xsdtoken, XsdSchema.xsdlanguage);
088            xsdGraph.addEdge(XsdSchema.xsdtoken, XsdSchema.xsdName);
089            xsdGraph.addEdge(XsdSchema.xsdtoken, XsdSchema.xsdNMTOKEN);
090            xsdGraph.addEdge(XsdSchema.xsdName, XsdSchema.xsdNCName);
091            xsdGraph.addEdge(XsdSchema.xsdNCName, XsdSchema.xsdID);
092            xsdGraph.addEdge(XsdSchema.xsdNCName, XsdSchema.xsdIDREF);
093            xsdGraph.addEdge(XsdSchema.xsdNCName, XsdSchema.xsdENTITY);
094    
095            // sub elements of decimal
096            xsdGraph.addEdge(XsdSchema.xsddecimal, XsdSchema.xsdinteger);
097            xsdGraph.addEdge(XsdSchema.xsdinteger, XsdSchema.xsdnonPositiveInteger);
098            xsdGraph.addEdge(XsdSchema.xsdinteger, XsdSchema.xsdlong);
099            xsdGraph.addEdge(XsdSchema.xsdinteger, XsdSchema.xsdnonNegativeInteger);
100            xsdGraph.addEdge(XsdSchema.xsdnonPositiveInteger, XsdSchema.xsdnegativeInteger);
101            xsdGraph.addEdge(XsdSchema.xsdlong, XsdSchema.xsdint);
102            xsdGraph.addEdge(XsdSchema.xsdnonNegativeInteger, XsdSchema.xsdunsignedLong);
103            xsdGraph.addEdge(XsdSchema.xsdnonNegativeInteger, XsdSchema.xsdpositiveInteger);
104            xsdGraph.addEdge(XsdSchema.xsdint, XsdSchema.xsdshort);
105            xsdGraph.addEdge(XsdSchema.xsdshort, XsdSchema.xsdbyte);
106            xsdGraph.addEdge(XsdSchema.xsdunsignedLong, XsdSchema.xsdunsignedInt);
107            xsdGraph.addEdge(XsdSchema.xsdunsignedInt, XsdSchema.xsdunsignedShort);
108            xsdGraph.addEdge(XsdSchema.xsdunsignedShort, XsdSchema.xsdunsignedByte);
109        }
110    
111        public static List<DefaultEdge> getShortestPath(String from, String to) {
112            List<DefaultEdge> path = DijkstraShortestPath.findPathBetween(xsdGraph, from, to);
113            return path;
114        }
115    
116        public static String findBestSuperXsdType(List<String> xsdTypeUris) {
117            List<GraphPath<String, DefaultEdge>> paths = new ArrayList<GraphPath<String, DefaultEdge>>();
118    
119            // for all given XSD types find a path from xsdRootNode to the XSD type
120            for (String xsdTypeUri : xsdTypeUris) {
121                // abort if one type == xsdRootNode (primitive case)
122                if (xsdTypeUri.equals(XsdSchema.xsdLiteral))
123                    return XsdSchema.xsdLiteral;
124                // otherwise, find the shortest path and add it to the paths list
125                GraphPathUtils<String, DefaultEdge> graphUtils = new GraphPathUtils<String, DefaultEdge>(xsdGraph);
126                GraphPath<String, DefaultEdge> graphPath = graphUtils.findShortestPath(XsdSchema.xsdLiteral, xsdTypeUri);
127                paths.add(graphPath);
128            }
129    
130            // find the last common element in the paths
131            int noOfPaths = paths.size();
132            GraphPathUtils<String, DefaultEdge> graphUtils = new GraphPathUtils<String, DefaultEdge>(xsdGraph);
133    
134            String type = XsdSchema.xsdLiteral;
135            String subType;
136    
137            while (true) {
138                // for first graph, find sub type
139                subType = graphUtils.getNextVertex(paths.get(0), type);
140                // no further sub types -> end of path -> return type
141                if (subType == null)
142                    return type;
143                // for all other graphs test if this node exists
144                for (int i = 1; i < noOfPaths; i++) {
145                    if (!graphUtils.hasVertex(paths.get(i), subType))
146                        return type;
147                }
148                // go down another level
149                type = subType;
150            }
151        }
152    
153    }