View Javadoc

1   /*
2    * Copyright 2004 Ronald Blaschke.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.rblasch.convert;
17  
18  import org.rblasch.convert.type.Type;
19  import org.rblasch.convert.graph.SparseWeightedDirectedGraph;
20  import org.rblasch.convert.graph.WeightedDirectedGraph;
21  import org.rblasch.convert.converters.OnceConverterFactory;
22  
23  import java.util.Set;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  /***
29   * @author Ronald Blaschke
30   */
31  public class ShortestPathSearch implements ConverterLookup {
32      private final Set/*<MetaConverter>*/ converters = new HashSet();
33      private final Set/*<ConverterFactory>*/ factories = new HashSet();
34      private final ShortestPathLookup lookup = new ShortestPathLookup(new SparseWeightedDirectedGraph());
35  
36      private static WeightedDirectedGraph convertersToGraph(final Set/*<MetaConverter>*/ cs) {
37          final WeightedDirectedGraph g = new SparseWeightedDirectedGraph();
38          for (final Iterator i = cs.iterator(); i.hasNext();) {
39              final MetaConverter mc = (MetaConverter) i.next();
40              g.addConnection(new TypeVertex(mc.getSourceType()),
41                      new ConverterEdge(mc, mc.getWeight()),
42                      new TypeVertex(mc.getDestinationType()));
43          }
44          return g;
45      }
46  
47      private static void runFactories(final ShortestPathLookup lookup, final List/*<ConverterFactory>*/ factories, final Type sourceType, final Type destinationType) {
48          for (final Iterator i = factories.iterator(); i.hasNext();) {
49              final ConverterFactory f = (ConverterFactory) i.next();
50              lookup.addGraph(convertersToGraph(f.create(sourceType, destinationType)));
51          }
52      }
53  
54      private static void runFactoriesOnAllKnownTypes(final ShortestPathLookup lookup, final Set/*<ConverterFactory>*/ factories) {
55          final WeightedDirectedGraph g = new SparseWeightedDirectedGraph();
56          final Set/*<Type>*/ allKnownTypes = lookup.getAllKnownTypes();
57          for (final Iterator i = allKnownTypes.iterator(); i.hasNext();) {
58              final Type sourceType = (Type) i.next();
59              for (final Iterator j = allKnownTypes.iterator(); j.hasNext();) {
60                  final Type destinationType = (Type) j.next();
61                  for (final Iterator k = factories.iterator(); k.hasNext();) {
62                      final ConverterFactory factory = (ConverterFactory) k.next();
63                      for (final Iterator l = factory.create(sourceType, destinationType).iterator(); l.hasNext();) {
64                          final MetaConverter mc = (MetaConverter) l.next();
65                          g.addConnection(new TypeVertex(mc.getSourceType()),
66                                  new ConverterEdge(mc, mc.getWeight()),
67                                  new TypeVertex(mc.getDestinationType()));
68                      }
69                      //Graphs.mergeInto(g, convertersToGraph());
70                  }
71              }
72          }
73          lookup.addGraph(g);
74      }
75  
76      String dumpGraph() {
77          return lookup.dumpGraph();
78      }
79  
80      public void addConverter(final MetaConverter converter) {
81          converters.add(converter);
82          lookup.addConverter(converter);
83      }
84  
85      public void addAllConverters(final Set/*<MetaConverter>*/ converters) {
86          for (final Iterator i = converters.iterator(); i.hasNext();) {
87              addConverter((MetaConverter) i.next());
88          }
89      }
90  
91      public void addOnceFactory(final OnceConverterFactory once) {
92          lookup.addAllConverters(once.createOnce());
93      }
94  
95      public void addFactory(final ConverterFactory factory) {
96          if (factory instanceof OnceConverterFactory) {
97              addOnceFactory((OnceConverterFactory) factory);
98          }
99          factory.setLookup(lookup);
100         factories.add(factory);
101     }
102 
103     public void addAllFactories(final Set/*<ConverterFactory>*/ factories) {
104         for (final Iterator i = factories.iterator(); i.hasNext();) {
105             addFactory((ConverterFactory) i.next());
106         }
107     }
108 
109     public MetaConverter lookup(final Type sourceType, final Type destinationType) {
110         lookup.addType(sourceType);
111         lookup.addType(destinationType);
112 
113         int numberOfTypes;
114         NoSuchConversionException pendingEx;
115         do {
116             numberOfTypes = lookup.getNumberOfKnownTypes();
117             try {
118                 return lookup.lookup(sourceType, destinationType);
119             } catch (final NoSuchConversionException ex) {
120                 pendingEx = ex;
121                 runFactoriesOnAllKnownTypes(lookup, factories);
122             }
123         } while (numberOfTypes != lookup.getNumberOfKnownTypes());
124         throw pendingEx;
125     }
126 }