KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > repository > DjRestriction


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  * Redistribution and use in source and binary forms, with or without
4  * modification, is permitted provided that the following conditions are met: -
5  * Redistributions of source code must retain the above copyright notice, this
6  * list of conditions and the following disclaimer. - Redistributions in binary
7  * form must reproduce the above copyright notice, this list of conditions and
8  * the following disclaimer in the documentation and/or other materials
9  * provided with the distribution. - All advertising materials mentioning
10  * features or use of this software must display the following acknowledgment:
11  * "This product includes Djeneric." - Products derived from this software may
12  * not be called "Djeneric" nor may "Djeneric" appear in their names without
13  * prior written permission of Genimen BV. - Redistributions of any form
14  * whatsoever must retain the following acknowledgment: "This product includes
15  * Djeneric." THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
16  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
17  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV,
19  * DJENERIC.ORG, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */

27 package com.genimen.djeneric.repository;
28
29 import java.util.ArrayList JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31
32 import com.genimen.djeneric.language.Messages;
33 import com.genimen.djeneric.repository.exceptions.CatalogException;
34 import com.genimen.djeneric.repository.exceptions.DjenericException;
35 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException;
36 import com.genimen.djeneric.repository.exceptions.RestrictionFailedException;
37
38 public class DjRestriction
39 {
40   DjProperty[] _restrictedPath = null;
41   DjProperty[] _restrictingPath = null;
42
43   String JavaDoc _originalExpression;
44   DjRelation _relation;
45
46   public DjRestriction(DjRelation relation, String JavaDoc expression) throws CatalogException
47   {
48     _relation = relation;
49     _originalExpression = expression;
50
51     try
52     {
53       parse(expression);
54     }
55     catch (ObjectNotDefinedException onde)
56     {
57       throw new CatalogException(onde);
58     }
59   }
60
61   protected void unregister()
62   {
63     // getMasterExtent().removeRestriction(this);
64
}
65
66   public DjRelation getRelation()
67   {
68     return _relation;
69   }
70
71   public String JavaDoc getExpression()
72   {
73     return _originalExpression;
74   }
75
76   public DjExtent getBaseExtent()
77   {
78     return _relation.getDetailExtent();
79   }
80
81   public DjExtent getMasterExtent()
82   {
83     return _relation.getMasterExtent();
84   }
85
86   public DjProperty getTopLevelRestrictedProperty()
87   {
88     return _restrictedPath[_restrictedPath.length - 1];
89   }
90
91   public DjProperty getTopLevelRestrictingProperty()
92   {
93     return _restrictingPath[_restrictedPath.length - 1];
94   }
95
96   public DjProperty getRestrictedProperty()
97   {
98     return _restrictedPath[0];
99   }
100
101   public DjProperty getRestrictingProperty()
102   {
103     return _restrictingPath[0];
104   }
105
106   public void parse(String JavaDoc expression) throws CatalogException, ObjectNotDefinedException
107   {
108     String JavaDoc matchOp = "==";
109
110     int eqIdx = expression.indexOf(matchOp);
111     if (eqIdx == -1)
112     {
113       matchOp = "=";
114       eqIdx = expression.indexOf(matchOp);
115       if (eqIdx == -1) throw new CatalogException(Messages.getString("DjRestriction.InvalidRestriction", expression));
116     }
117
118     String JavaDoc left = expression.substring(0, eqIdx).trim();
119     String JavaDoc right = expression.substring(eqIdx + matchOp.length()).trim();
120
121     DjProperty propLeft = _relation.getDetailExtent().getProperty(left);
122     DjProperty propRight = _relation.getDetailExtent().getProperty(right);
123
124     if ((propLeft.getType() instanceof DjExtent) && (propRight.getType() instanceof DjExtent))
125     {
126       DjExtent typeLeft = (DjExtent) propLeft.getType();
127       DjExtent typeRight = (DjExtent) propRight.getType();
128       if (!typeLeft.isInstanceof(typeRight) && !typeRight.isInstanceof(typeLeft))
129       {
130         throw new CatalogException(Messages.getString("DjRestriction.InvalidRestrictionTypes", expression));
131       }
132     }
133     else throw new CatalogException(Messages.getString("DjRestriction.InvalidRestrictionTypes", expression));
134
135     DjProperty[] leftPath = parsePart(left);
136     DjProperty[] rightPath = parsePart(right);
137
138     if (leftPath.length < 1)
139     {
140       throw new CatalogException(Messages.getString("DjRestriction.InvalidRestrictionLeft"));
141     }
142     if (rightPath.length < 1)
143     {
144       throw new CatalogException(Messages.getString("DjRestriction.InvalidRestrictionRight"));
145     }
146
147     DjProperty leftProperty = leftPath[leftPath.length - 1];
148     DjProperty rightProperty = rightPath[rightPath.length - 1];
149
150     if ((leftProperty.getExtent() != getMasterExtent()) && (rightProperty.getExtent() != getMasterExtent()))
151     {
152       throw new CatalogException(Messages.getString("DjRestriction.MasterNotReferenced", getMasterExtent().getName()));
153     }
154
155     boolean pathToMasterOnLeft = leftPath[leftPath.length - 1].getExtent() == getMasterExtent();
156
157     // Beware of recursive relations: in that case the master extent could be
158
// last on both sides of
159
// the path. If that is the case then we consider the shortest path to be
160
// the one that is
161
// the compare value, and the longest the path the one that needs to be
162
// evaluated.
163
// So:
164

165     if (leftPath[leftPath.length - 1].getExtent() == getMasterExtent()
166         && rightPath[rightPath.length - 1].getExtent() == getMasterExtent())
167     {
168       pathToMasterOnLeft = leftPath.length > rightPath.length;
169     }
170
171     if (pathToMasterOnLeft)
172     {
173       _restrictedPath = leftPath;
174       _restrictingPath = rightPath;
175     }
176     else
177     {
178       _restrictedPath = rightPath;
179       _restrictingPath = leftPath;
180     }
181
182     // Now mark all properties that are part of the restricting path as
183
// restricted (they can not be updated
184
// because this could break the restriction.
185
// Length - 1 because the lowest level is not restricted; see the
186
// _restrictingPath[i+1] below
187
for (int i = 0; i < _restrictingPath.length - 1; i++)
188     {
189       DjProperty prop = _restrictingPath[i];
190       DjRelation rel = prop.getExtent().getMasterRelationByPropertyName(prop.getName());
191
192       // Ok, this relation is restricting updates of the property one level
193
// higher.
194
_restrictingPath[i + 1].addPropertyRestriction(new DjPropertyRestriction(rel, this));
195     }
196
197     for (int i = 0; i < _restrictedPath.length; i++)
198     {
199       DjProperty prop = _restrictedPath[i];
200       prop.setIsPartOfRestrictedPath(true);
201     }
202   }
203
204   protected DjProperty[] parsePart(String JavaDoc part) throws CatalogException, ObjectNotDefinedException
205   {
206     ArrayList JavaDoc path = new ArrayList JavaDoc();
207
208     DjProperty property = null;
209     DjExtent currentExtent = getBaseExtent();
210     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(part, ".");
211
212     while (st.hasMoreElements())
213     {
214       property = currentExtent.getProperty(st.nextToken().trim());
215       path.add(property);
216       if (!(property.getType() instanceof DjExtent))
217       {
218         throw new CatalogException(Messages.getString("global.propNotUsed", property.getName()));
219       }
220       currentExtent = (DjExtent) property.getType();
221     }
222     return (DjProperty[]) path.toArray(new DjProperty[0]);
223   }
224
225   public long evaluate(DjObject obj) throws DjenericException
226   {
227     if (obj.getExtent() != getBaseExtent())
228     {
229       throw new DjenericException(Messages.getString("DjRestriction.WrongType", obj.getExtent().getObjectType(),
230                                                      getBaseExtent().getObjectType()));
231     }
232
233     for (int i = 0; i < _restrictingPath.length; i++)
234     {
235       Object JavaDoc anObj = obj.get(_restrictingPath[i].getName());
236
237       if (anObj == null)
238       {
239         throw new RestrictionFailedException(Messages
240             .getString("DjRestriction.PropNull", _restrictingPath[i].getName()));
241       }
242       if (!(anObj instanceof DjObject))
243       {
244         throw new DjenericException(Messages.getString("global.propNotUsed", _restrictingPath[i].getName()));
245       }
246       obj = (DjObject) anObj;
247     }
248     return obj.getObjectId();
249   }
250 }
Popular Tags