1   
2   package org.molwind.chemical.model;
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  import org.molwind.graph.DefaultEntityGraph;
22  import org.molwind.graph.EntityGraph;
23  import org.molwind.graph.EntityGraphAnalyzer;
24  import org.molwind.graph.EntityVertex;
25  import org.molwind.model.Identity;
26  import org.molwind.model.PartOf;
27  import org.molwind.model.Relationship;
28  import org.molwind.model.RelationshipResolver;
29  import org.molwind.model.WorldEntity;
30  import org.molwind.util.MolwindLogger;
31  import org.openscience.cdk.tools.MFAnalyser;
32  
33  import org.openscience.cdk.interfaces.IMolecule;
34  
35  
36  
37  
38  
39  
40  
41  public class SubstructureResolver
42  implements RelationshipResolver, EntityGraphAnalyzer, Identity {
43  
44      
45      
46      private EntityGraph compounds;
47      private boolean analyzed;
48      
49      private String idName;
50     
51      private String parentName;
52  
53      
54  
55  
56  
57      public String getParentName(){
58  
59  	return parentName;
60      }
61  
62      
63  
64  
65  
66      public void setParentName(String newParentName) {
67  	this.parentName = newParentName;
68      }
69  
70      
71  
72      
73  
74  
75  
76  
77  
78  
79  
80  
81      public SubstructureResolver(final String newParentName,
82              final String newIdName) {
83          parentName = newParentName;
84  
85          idName = newIdName;
86          analyzed = false;
87          compounds = new DefaultEntityGraph();
88      }
89      
90  
91      private  double getMolecularWeight(IMolecule molecule){
92  	if(molecule==null) return 0.0F;
93  	
94  	MFAnalyser mfa = new MFAnalyser(molecule);
95  	try {
96  	    return mfa.getCanonicalMass();
97  	} catch (Exception e) {
98  	    return 0.0f;
99  	}
100 	
101 	
102 	
103     }
104     
105  
106 
107 
108     private String getId(final ChemicalEntity chemicalEntity) {
109         String id = chemicalEntity.getAttribute(idName);
110 
111         if (id == null) {
112             id = String.valueOf(System.currentTimeMillis());
113             chemicalEntity.setAttribute(idName, id);
114         }
115         return id;
116     }
117 
118     private boolean addRelation(final ChemicalEntity chemicalEntity1,
119             final ChemicalEntity chemicalEntity2) {
120         if ((chemicalEntity1 == null) || (chemicalEntity2 == null)) {
121             return false;
122         }
123 
124         PartOf relation = new PartOf(chemicalEntity1, chemicalEntity2);
125         chemicalEntity1.addRelationship(relation);
126         chemicalEntity2.addRelationship(relation);
127 
128         String id1 = getId(chemicalEntity1);
129         String id2 = getId(chemicalEntity2);
130 	
131 	IMolecule molecule1 = chemicalEntity1.getMolecule();
132 	IMolecule molecule2 = chemicalEntity2.getMolecule();
133 	
134 	int edgeWeight = molecule1.getAtomCount()+molecule2.getAtomCount();
135 
136         compounds.addEntity(id1, chemicalEntity1);
137         compounds.addEntity(id2, chemicalEntity2);
138         compounds.addEdge(id1, id2, relation,edgeWeight);
139 
140 
141         return true;
142     }
143 
144 
145     
146 
147 
148 
149 
150 
151 
152 
153 
154 
155     public boolean related(final WorldEntity entity1,
156             final WorldEntity entity2) {
157 
158         if ((entity1 == null)
159                 || (entity2 == null)
160                 || !(entity1 instanceof ChemicalEntity)
161                 || !(entity2 instanceof ChemicalEntity)) {
162             return false;
163         }
164 
165         ChemicalEntity chemicalEntity1 = (ChemicalEntity) entity1;
166         ChemicalEntity chemicalEntity2 = (ChemicalEntity) entity2;
167         String parentId1 = chemicalEntity1.getAttribute(parentName);
168         String id1 = getId(chemicalEntity1);
169         String parentId2 = chemicalEntity2.getAttribute(parentName);
170         String id2 = getId(chemicalEntity2);
171 
172 	       
173 	 
174 	boolean related = false;
175         if (parentId1 != null) {
176             if (parentId1.equals(id2)) {
177                 return addRelation(chemicalEntity1, chemicalEntity2);
178             } else {
179                 related = addRelation(chemicalEntity1,
180                         (ChemicalEntity) compounds.findEntity(parentId1));
181             }
182         }
183 
184         if (parentId2 != null) {
185             if (parentId2.equals(id1)) {
186                 return addRelation(chemicalEntity2, chemicalEntity1);
187             } else {
188                 related = addRelation(chemicalEntity2,
189                         (ChemicalEntity) compounds.findEntity(parentId2));
190             }
191         }
192 
193         if (!related) {
194             compounds.addEntity(id1, chemicalEntity1);
195             compounds.addEntity(id2, chemicalEntity2);
196         }
197 
198         return false;
199     }
200 
201     
202 
203 
204 
205 
206 
207 
208     public EntityGraph resolve() {
209         if (!analyzed) {
210             compounds.analyze(this);
211             analyzed = true;
212         }
213         return compounds;
214     }
215 
216     
217 
218 
219 
220 
221 
222 
223 
224 
225 
226     public boolean analyze(final EntityGraph graph,
227             final EntityVertex vertex) {
228         ChemicalEntity chemicalEntity1 = (ChemicalEntity) vertex.getEntity();
229         String parentId = chemicalEntity1.getAttribute(parentName);
230         if (parentId == null) {
231             return true;
232         }
233 
234         ChemicalEntity chemicalEntity2 =
235             (ChemicalEntity) graph.findEntity(parentId);
236         if (chemicalEntity2 == null) {
237             MolwindLogger.warn("Missing parent id " + parentId, null);
238             return true;
239         }
240 
241         Relationship[] relations =
242             chemicalEntity1.hasRelationship(chemicalEntity2);
243         if (relations.length > 0) {
244             return true;
245         }
246 
247         PartOf relation = new PartOf(chemicalEntity1, chemicalEntity2);
248         chemicalEntity1.addRelationship(relation);
249         chemicalEntity2.addRelationship(relation);
250         return true;
251     }
252 
253     
254 
255 
256 
257 
258 
259 
260 
261 
262 
263     public boolean identical(final WorldEntity entity1,
264             final WorldEntity entity2) {
265         String id1 = getId((ChemicalEntity) entity1);
266         String id2 = getId((ChemicalEntity) entity2);
267         return id1.equals(id2);
268     }
269 
270 }