From: <bea...@us...> - 2006-10-13 17:22:46
|
Revision: 274 http://svn.sourceforge.net/cishell/?rev=274&view=rev Author: bearsfan Date: 2006-10-13 10:22:41 -0700 (Fri, 13 Oct 2006) Log Message: ----------- added multi step conversions. Modified Paths: -------------- trunk/core/org.cishell.reference/META-INF/MANIFEST.MF trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/ConverterImpl.java trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/DataConversionServiceImpl.java Modified: trunk/core/org.cishell.reference/META-INF/MANIFEST.MF =================================================================== --- trunk/core/org.cishell.reference/META-INF/MANIFEST.MF 2006-10-13 17:22:17 UTC (rev 273) +++ trunk/core/org.cishell.reference/META-INF/MANIFEST.MF 2006-10-13 17:22:41 UTC (rev 274) @@ -19,3 +19,4 @@ org.cishell.reference.app.service.scheduler, org.cishell.reference.service.conversion Eclipse-LazyStart: true +Require-Bundle: edu.uci.ics.jung Modified: trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/ConverterImpl.java =================================================================== --- trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/ConverterImpl.java 2006-10-13 17:22:17 UTC (rev 273) +++ trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/ConverterImpl.java 2006-10-13 17:22:41 UTC (rev 274) @@ -33,7 +33,7 @@ * * @author Bruce Herr (bh...@bh...) */ -public class ConverterImpl implements Converter, AlgorithmFactory, AlgorithmProperty { +public class ConverterImpl implements Converter, AlgorithmFactory, AlgorithmProperty, Comparable { private ServiceReference[] refs; private BundleContext bContext; private Dictionary props; @@ -121,6 +121,25 @@ public MetaTypeProvider createParameters(Data[] dm) { return null; } + + public boolean equals(Object o) { + boolean equals = false; + if (o instanceof Converter) { + ServiceReference[] otherServiceReference = ((Converter)o).getConverterChain(); + if (refs.length == otherServiceReference.length) { + for (int i = 0; i < otherServiceReference.length; i++) { + if (refs[i].getProperty(Constants.SERVICE_ID).equals(otherServiceReference[i].getProperty(Constants.SERVICE_ID))) { + equals = true; + } else { + equals = false; + break; + } + } + } + } + + return equals; + } private class ConverterAlgorithm implements Algorithm { Data[] inDM; @@ -151,4 +170,8 @@ return dm; } } + + public int compareTo(Object o) { + return equals(o) ? 0 : 1; + } } Modified: trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/DataConversionServiceImpl.java =================================================================== --- trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/DataConversionServiceImpl.java 2006-10-13 17:22:17 UTC (rev 273) +++ trunk/core/org.cishell.reference/src/org/cishell/reference/service/conversion/DataConversionServiceImpl.java 2006-10-13 17:22:41 UTC (rev 274) @@ -14,12 +14,15 @@ package org.cishell.reference.service.conversion; import java.io.File; +import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.cishell.framework.CIShellContext; @@ -29,48 +32,166 @@ import org.cishell.service.conversion.Converter; import org.cishell.service.conversion.DataConversionService; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; -public class DataConversionServiceImpl implements DataConversionService, AlgorithmProperty { +import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath; +import edu.uci.ics.jung.graph.Edge; +import edu.uci.ics.jung.graph.Graph; +import edu.uci.ics.jung.graph.Vertex; +import edu.uci.ics.jung.graph.impl.DirectedSparseEdge; +import edu.uci.ics.jung.graph.impl.DirectedSparseGraph; +import edu.uci.ics.jung.graph.impl.SparseVertex; +import edu.uci.ics.jung.io.GraphMLFile; +import edu.uci.ics.jung.utils.UserDataContainer; + +public class DataConversionServiceImpl implements DataConversionService, AlgorithmProperty, ServiceListener { + public final static String SERVICE_LIST = "SERVICE_LIST"; + private BundleContext bContext; private CIShellContext ciContext; + private Map dataTypeToVertex; + private Graph graph; + public DataConversionServiceImpl(BundleContext bContext, CIShellContext ciContext) { this.bContext = bContext; this.ciContext = ciContext; + + String filter = "(&("+ALGORITHM_TYPE+"="+TYPE_CONVERTER+")" + + "("+IN_DATA+"=*) " + + "("+OUT_DATA+"=*)" + + "(!("+REMOTE+"=*)))"; + + try { + this.bContext.addServiceListener(this, filter); + } catch (InvalidSyntaxException e) { + e.printStackTrace(); + } + assembleGraph(); } /** - * TODO: Only provides a direct conversion, need to improve - * - * @see org.cishell.service.conversion.DataConversionService#findConverters(java.lang.String, java.lang.String) + * Assemble the directed graph of converters + * */ - public Converter[] findConverters(String inFormat, String outFormat) { + private void assembleGraph() { + graph = new DirectedSparseGraph(); + + dataTypeToVertex = new Hashtable(); + try { String filter = "(&("+ALGORITHM_TYPE+"="+TYPE_CONVERTER+")" + - "("+IN_DATA+"="+inFormat+") " + - "("+OUT_DATA+"="+outFormat+")" + + "("+IN_DATA+"=*) " + + "("+OUT_DATA+"=*)" + "(!("+REMOTE+"=*)))"; ServiceReference[] refs = bContext.getServiceReferences( AlgorithmFactory.class.getName(), filter); - if (refs != null && refs.length > 0) { - Converter[] converters = new Converter[refs.length]; - for (int i=0; i < converters.length; i++) { - converters[i] = new ConverterImpl(bContext, ciContext, new ServiceReference[]{refs[i]}); - } - - return converters; - } else { - return new Converter[0]; - } + if (refs != null) { + for (int i = 0; i < refs.length; ++i) { + String inData = (String) refs[i] + .getProperty(AlgorithmProperty.IN_DATA); + String outData = (String) refs[i] + .getProperty(AlgorithmProperty.OUT_DATA); + + addServiceReference(inData, outData, refs[i]); + } + } } catch (InvalidSyntaxException e) { throw new RuntimeException(e); } + } + + /** + * TODO: Only provides a direct conversion, need to improve + * + * @see org.cishell.service.conversion.DataConversionService#findConverters(java.lang.String, java.lang.String) + */ + public Converter[] findConverters(String inFormat, String outFormat) { + //saveGraph(); + if (inFormat != null && inFormat.length() > 0 && + outFormat != null && outFormat.length() > 0) { + + return getConverters(inFormat, outFormat); + } + return new Converter[0]; } + private Converter[] getConverters(String inFormat, String outFormat) { + String inFilter = "(&(" + ALGORITHM_TYPE + "=" + TYPE_CONVERTER + ")" + + "(" + IN_DATA + "=" + inFormat + ") " + "(" + OUT_DATA + + "=*)" + "(!(" + REMOTE + "=*)))"; + + String outFilter = "(&(" + ALGORITHM_TYPE + "=" + TYPE_CONVERTER + ")" + + "(" + IN_DATA + "=*) " + "(" + OUT_DATA + "=" + outFormat + + ")" + "(!(" + REMOTE + "=*)))"; + + try { + ServiceReference[] inRefs = bContext.getServiceReferences( + AlgorithmFactory.class.getName(), inFilter); + ServiceReference[] outRefs = bContext.getServiceReferences( + AlgorithmFactory.class.getName(), outFilter); + + if (inRefs != null && outRefs != null) { + Set inFileTypeSet = new HashSet(); + for (int i = 0; i < inRefs.length; ++i) { + inFileTypeSet.add(inRefs[i] + .getProperty(AlgorithmProperty.IN_DATA)); + } + Set outFileTypeSet = new HashSet(); + for (int i = 0; i < outRefs.length; ++i) { + outFileTypeSet.add(outRefs[i] + .getProperty(AlgorithmProperty.OUT_DATA)); + } + + Collection converterList = new HashSet(); + for (Iterator i = inFileTypeSet.iterator(); i.hasNext();) { + String srcDataType = (String) i.next(); + for (Iterator j = outFileTypeSet.iterator(); j.hasNext();) { + Converter converter = getConverter( srcDataType, + (String) j.next()); + if (converter != null) + converterList.add(converter); + } + } + return (Converter[]) converterList.toArray(new Converter[0]); + } + } catch (InvalidSyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return new Converter[0]; + } + + private Converter getConverter(String inType, String outType) { + Vertex srcVertex = (Vertex)dataTypeToVertex.get(inType); + Vertex tgtVertex = (Vertex)dataTypeToVertex.get(outType); + + if (srcVertex != null && tgtVertex != null) { + DijkstraShortestPath shortestPathAlg = new DijkstraShortestPath(graph); + List edgeList = shortestPathAlg.getPath(srcVertex, tgtVertex); + + if (edgeList.size() > 0) { + ServiceReference[] serviceReferenceArray = new ServiceReference[edgeList + .size()]; + for (int i = 0; i < serviceReferenceArray.length; ++i) { + Edge edge = (Edge) edgeList.get(i); + AbstractList converterList = (AbstractList) edge + .getUserDatum(SERVICE_LIST); + serviceReferenceArray[i] = (ServiceReference) converterList + .get(0); + } + return new ConverterImpl(bContext, ciContext, serviceReferenceArray); + } + } + return null; + } + /** * @see org.cishell.service.conversion.DataConversionService#findConverters(java.lang.String, java.lang.String, int, java.lang.String) */ @@ -93,11 +214,11 @@ String format = data.getFormat(); - List list = new ArrayList(); + Set set = new HashSet(); Converter[] converters = new Converter[0]; if (format != null) { converters = findConverters(format, outFormat); - list.addAll(Arrays.asList(converters)); + set.addAll(new HashSet(Arrays.asList(converters))); } if (!(data.getData() instanceof File) && data.getData() != null) { @@ -105,11 +226,11 @@ while (iter.hasNext()) { Class c = (Class) iter.next(); converters = findConverters(c.getName(), outFormat); - list.addAll(Arrays.asList(converters)); + set.addAll(new HashSet(Arrays.asList(converters))); } } - return (Converter[]) list.toArray(new Converter[0]); + return (Converter[]) set.toArray(new Converter[0]); } protected Collection getClassesFor(Class clazz) { @@ -151,4 +272,101 @@ return inDM; } + + + public void serviceChanged(ServiceEvent event) { + ServiceReference inServiceRef = event.getServiceReference(); + + String inDataType = (String)inServiceRef.getProperty(AlgorithmProperty.IN_DATA); + String outDataType = (String)inServiceRef.getProperty(AlgorithmProperty.OUT_DATA); + + if (event.getType() == ServiceEvent.MODIFIED) { + removeServiceReference(inDataType, outDataType, inServiceRef); + addServiceReference(inDataType, outDataType, inServiceRef); + } + else if(event.getType() == ServiceEvent.REGISTERED) { + addServiceReference(inDataType, outDataType, inServiceRef); + } + else if(event.getType() == ServiceEvent.UNREGISTERING) { + removeServiceReference(inDataType, outDataType, inServiceRef); + } + } + + private void removeServiceReference(String srcDataType, String tgtDataType, ServiceReference serviceReference) { + if (srcDataType != null && tgtDataType != null) { + Vertex srcVertex = (Vertex) dataTypeToVertex.get(srcDataType); + Vertex tgtVertex = (Vertex) dataTypeToVertex.get(tgtDataType); + String pid = (String) serviceReference + .getProperty(Constants.SERVICE_PID); + + if (srcVertex != null && tgtVertex != null) { + Edge edge = srcVertex.findEdge(tgtVertex); + if (edge != null) { + AbstractList serviceList = (AbstractList) edge + .getUserDatum(SERVICE_LIST); + for (Iterator iterator = serviceList.iterator(); iterator + .hasNext();) { + ServiceReference currentServiceReference = (ServiceReference) iterator + .next(); + String currentPid = (String) currentServiceReference + .getProperty(Constants.SERVICE_PID); + + if (pid.equals(currentPid)) { + iterator.remove(); + } + } + if (serviceList.isEmpty()) { + graph.removeEdge(edge); + } + } + } + } + } + + private void addServiceReference(String srcDataType, String tgtDataType, ServiceReference serviceReference) { + if (srcDataType != null && srcDataType.length() > 0 + && tgtDataType != null && tgtDataType.length() > 0) { + Vertex srcVertex = getVertex(srcDataType); + Vertex tgtVertex = getVertex(tgtDataType); + + removeServiceReference(srcDataType, tgtDataType, serviceReference); + + Edge directedEdge = srcVertex.findEdge(tgtVertex); + if (directedEdge == null) { + directedEdge = new DirectedSparseEdge(srcVertex, tgtVertex); + graph.addEdge(directedEdge); + } + + AbstractList serviceList = (AbstractList) directedEdge.getUserDatum(SERVICE_LIST); + if (serviceList == null) { + serviceList = new ArrayList(); + serviceList.add(serviceReference); + } + directedEdge.setUserDatum(SERVICE_LIST, serviceList, + new UserDataContainer.CopyAction.Shared()); + } + } + + private Vertex getVertex(String dataType) { + Vertex vertex = (SparseVertex)dataTypeToVertex.get(dataType); + if (vertex== null) { + vertex = new SparseVertex(); + vertex.addUserDatum("label", dataType, + new UserDataContainer.CopyAction.Shared()); + graph.addVertex(vertex); + dataTypeToVertex.put(dataType, vertex); + } + return vertex; + } + + private void saveGraph() { + GraphMLFile writer = new GraphMLFile(); + Graph g = (Graph)graph.copy(); + for (Iterator i = g.getEdges().iterator(); i.hasNext();) { + Edge e = (Edge)i.next(); + e.removeUserDatum(SERVICE_LIST); + } + writer.save(g, System.getProperty("user.home") + File.separator + "convertGraph.xml"); + + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |