View Javadoc

1   package org.molwind.chemical.model;
2   
3   /*
4    * This file is part of Molwind.
5    *
6    * Molwind is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * Molwind is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with Molwind. If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  import java.awt.Color;
21  import java.awt.Graphics;
22  import java.awt.image.BufferedImage;
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.awt.geom.Point2D;
26  
27  import org.openscience.cdk.exception.CDKException;
28  import org.openscience.cdk.inchi.InChIGenerator;
29  import org.openscience.cdk.inchi.InChIGeneratorFactory;
30  import org.openscience.cdk.interfaces.IMolecule;
31  
32  
33  import org.molwind.chemical.view.MoleculeRenderer;
34  import org.molwind.chemical.view.MoleculeRendererFactory;
35  import org.molwind.model.Identity;
36  import org.molwind.model.PlacedWorldEntity;
37  import org.molwind.model.Relationship;
38  import org.molwind.model.WorldEntity;
39  import org.molwind.util.MolwindLogger;
40  
41  /**
42   * ChemicalEntity represents a chemical entity in a Molwind world.
43   *
44   * @author <a href="mailto:oliver.karch@molwind.org">Oliver Karch</a>
45   * @version 1.0
46   */
47  public class ChemicalEntity extends PlacedWorldEntity {
48  
49      private ArrayList relations;
50      private IMolecule molecule;
51      private Identity identity;
52      private MoleculeRenderer moleculeRenderer;
53      private boolean firstSetX=true;
54      private boolean firstSetY=true;
55   
56      private static InChIGeneratorFactory inChIFactory;
57      private String parentId;
58      
59  
60  
61      
62      
63  
64      /**
65       * Creates a new empty chemical entity.
66       */
67      public ChemicalEntity() {
68          super();
69          relations = new ArrayList();
70          identity = null;
71          moleculeRenderer = MoleculeRendererFactory.getRenderer();
72      }
73  
74      /**
75       * Creates a new empty chemical entity.
76       *
77       * @param newMolecule
78       *      the new molecule value
79       */
80      public ChemicalEntity(final IMolecule newMolecule) {
81          this();
82          molecule = newMolecule;
83      }
84  
85      /**
86       * Get the Identity value.
87       *
88       * @return
89       *      the Identity value
90       */
91      public Identity getIdentity() {
92          return identity;
93      }
94  
95      /**
96       * Set the Identity value.
97       *
98       * @param newIdentity
99       *      the new Identity value
100      */
101     public void setIdentity(final Identity newIdentity) {
102         this.identity = newIdentity;    }
103 
104     /**
105      * Adds a new relationship if it is not existing already.
106      *
107      * @param relation
108      *      the relationship
109      */
110     public void addRelationship(final Relationship relation) {
111         if (!existRelationship(relation)) {
112             super.addRelationship(relation);
113         }
114     }
115 
116     /**
117      * Tests whether there are relationships between this entity and the
118      * given entity.
119      *
120      * @param entity
121      *      the entity to test relationship
122      * @return
123      *      an array of relationship objects (which can be empty)
124      */
125     public Relationship[] hasRelationship(final ChemicalEntity entity) {
126         Iterator it = getRelationships();
127         ArrayList al = new ArrayList();
128 
129         while (it.hasNext()) {
130             Relationship relation = (Relationship) it.next();
131 
132             WorldEntity worldEntity = relation.getLeft();
133             if ((worldEntity != null)
134                     && (worldEntity instanceof ChemicalEntity)
135                     && (worldEntity.equals(entity))) {
136                 al.add(relation);
137                 continue;
138             }
139 
140             worldEntity = relation.getRight();
141             if ((worldEntity != null)
142                     && (worldEntity instanceof ChemicalEntity)
143                     && (worldEntity.equals(entity))) {
144                 al.add(relation);
145             }
146         }
147 
148         Relationship[] relations = new Relationship[al.size()];
149         return (Relationship[]) al.toArray(relations);
150     }
151 
152     /**
153      * Get the MoleculeRenderer value.
154      *
155      * @return
156      *      the MoleculeRenderer value
157      */
158     public MoleculeRenderer getMoleculeRenderer() {
159         return moleculeRenderer;
160     }
161 
162     /**
163      * Set the MoleculeRenderer value.
164      *
165      * @param newMoleculeRenderer
166      *      the new MoleculeRenderer value
167      */
168     public void setMoleculeRenderer(
169             final MoleculeRenderer newMoleculeRenderer) {
170         this.moleculeRenderer = newMoleculeRenderer;
171     }
172 
173     /**
174      * Renders an image representation of this entity.
175      *
176      * @return
177      *      an empty image
178      */
179     public BufferedImage getDrawing() {
180         MoleculeRenderer moleculeRenderer = getMoleculeRenderer();
181         try {
182             return moleculeRenderer.getImage(this);
183         } catch (CDKException cdke) {
184             MolwindLogger.warn(cdke);
185             cdke.printStackTrace();
186             return getEmptyImage();
187         }
188     }
189 
190     private BufferedImage getEmptyImage() {
191         BufferedImage emptyImage =
192             new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
193         Graphics graphic = emptyImage.getGraphics();
194         graphic.setColor(Color.white);
195         graphic.fillRect(0, 0, 1, 1);
196         return emptyImage;
197     }
198 
199     private static InChIGeneratorFactory getInChiFactory()
200     throws CDKException {
201         if (inChIFactory == null) {
202             inChIFactory = new InChIGeneratorFactory();
203         }
204         return inChIFactory;
205     }
206 
207     /**
208      * Tests whether two objects are identical by using the Identity strategy
209      * which has been provided (optionally).
210      *
211      * @param object
212      *      the object to compare to
213      * @return
214      *      true if this object equals to the given object
215      */
216     public boolean equals(final Object object) {
217         if (!(object instanceof ChemicalEntity)) {
218             return false;
219         }
220 
221         ChemicalEntity chemicalEntity = (ChemicalEntity) object;
222 
223         if (identity != null) {
224             return identity.identical(this, chemicalEntity);
225         }
226 
227         IMolecule molecule1 = chemicalEntity.getMolecule();
228         IMolecule molecule2 = this.getMolecule();
229 
230         boolean identical = false;
231 
232         if ((molecule1 != null) && (molecule2 != null)) {
233             try {
234                 InChIGeneratorFactory inFact = getInChiFactory();
235                 InChIGenerator ig1 = inFact.getInChIGenerator(molecule1);
236                 String inchi1 = ig1.getInchi();
237                 InChIGenerator ig2 = inFact.getInChIGenerator(molecule2);
238                 String inchi2 = ig2.getInchi();
239                 identical = inchi1.equals(inchi2);
240             } catch (CDKException cex) {
241                 MolwindLogger.warn("EQUALS", cex);
242                 identical = false;
243             }
244         }
245         return identical;
246     }
247 
248     /**
249      * Returns a hash code value for this relationship. The method must be
250      * defined, because this class overrides <code>equals(Object)</code>.
251      * <p>
252      * TODO Auto-generated hashCode() method
253      *
254      * @return
255      *      a hash code value for this object
256      */
257     public int hashCode() {
258         assert false : "hashCode not designed";
259         return 36697;
260     }
261     
262     /**
263      * Return the molecule object
264      * 
265      * @return
266      *      IMolecule
267      *
268      *
269      */
270     public IMolecule getMolecule() {
271         if (molecule != null) {
272             return molecule;
273         }
274         return null;
275     }
276     
277     /**
278      * Sets the molecule object 
279      *
280      * @param
281      *     IMolecule
282      *
283      */
284     
285     public void setMolecule(IMolecule mol){
286 	molecule=mol;
287 	
288     }
289     
290     
291 
292     /**
293      * Returns the value of the attribute with the given name.
294      *
295      * @param name
296      *      the name of the attribute
297      * @return
298      *      the value of the attribute
299      */
300     public String getAttribute(final String name) {
301 
302 	IMolecule mol = getMolecule();
303 
304 	return (String) mol.getProperty(name );
305     }
306     
307      /**
308      * Returns int for the bigness of the entity
309      *
310      * @return 
311      *      the bigness of the entity
312      */
313     public int getDimension(){
314 	return molecule.getAtomCount();
315     
316     }
317 
318     /**
319      * Sets the value of the attribute with the given name.
320      *
321      * @param name
322      *      the name of the attribute
323      * @param value
324      *      the value of the attribute
325      */
326     public void setAttribute(final String name, final Object value) {
327 	putAttribute( name, value );
328 	molecule.setProperty(name,value);
329     }
330     
331     
332  
333     
334     
335     private ArrayList<WorldEntity> getChildren(){
336 	ArrayList result = new ArrayList<WorldEntity>();
337 
338 	Iterator it = getRelationships();
339 
340 	while(it.hasNext()){
341 	    Relationship rel =(Relationship)it.next();
342 	    if(!rel.getLeft().equals(this)){
343 		result.add(rel.getLeft());
344 		
345 	    }
346 	    
347 	}
348 	return result;
349     }
350     
351 
352     /**
353      * Get the X value.
354      * @return the X value.
355      */
356     public double getX() {
357 	return x;
358     }
359     
360     ArrayList<WorldEntity> childList=null;
361     /**
362      * Set the X value.
363      * @param newX The new X value.
364      */
365     public void setX(double newX) {
366 	if(firstSetX){
367 	    super.setX(newX);
368 	    firstSetX=false;
369 
370 	}else{
371 
372 	    double delta =newX- this.x ;
373 	    super.setX(newX);
374 	    if(childList==null)
375 		childList = getChildren();
376 	    for(WorldEntity worldEntity: childList){
377 
378 		PlacedWorldEntity pwe = (PlacedWorldEntity)worldEntity;
379 		pwe.setDeltaX(delta);
380 	    }
381 	}
382     }
383     
384   
385 
386     /**
387      * Get the Y value.
388      * @return the Y value.
389      */
390     public double getY() {
391 	return y;
392     }
393 
394     /**
395      * Set the Y value.
396      * @param newY The new Y value.
397      */
398     public void setY(double newY) {
399 	if(firstSetY){
400 	    super.setY(newY);
401 	    firstSetY = false;
402 
403 	}else{
404 
405 	    double delta = newY-this.y;
406 	    super.setY(newY);
407 	    if(childList==null)
408 		childList = getChildren();
409 	 
410 	    for(WorldEntity worldEntity: childList){
411 		PlacedWorldEntity pwe = (PlacedWorldEntity)worldEntity;
412 		pwe.setDeltaY(delta);
413 	    }
414 	}
415     }
416 
417    
418     
419     
420    
421     
422   
423     
424     
425     
426     
427    
428   
429     
430 
431 }