001: /*
002: * This file is part of the GeOxygene project source files.
003: *
004: * GeOxygene aims at providing an open framework which implements OGC/ISO specifications for
005: * the development and deployment of geographic (GIS) applications. It is a open source
006: * contribution of the COGIT laboratory at the Institut Géographique National (the French
007: * National Mapping Agency).
008: *
009: * See: http://oxygene-project.sourceforge.net
010: *
011: * Copyright (C) 2005 Institut Géographique National
012: *
013: * This library is free software; you can redistribute it and/or modify it under the terms
014: * of the GNU Lesser General Public License as published by the Free Software Foundation;
015: * either version 2.1 of the License, or any later version.
016: *
017: * This library is distributed in the hope that it will be useful, but WITHOUT ANY
018: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
019: * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser General Public License along with
022: * this library (see file LICENSE if present); if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: *
025: */
026:
027: package fr.ign.cogit.geoxygene.example;
028:
029: import java.util.Iterator;
030: import java.util.List;
031:
032: import fr.ign.cogit.geoxygene.datatools.Geodatabase;
033: import fr.ign.cogit.geoxygene.datatools.ojb.GeodatabaseOjbFactory;
034: import fr.ign.cogit.geoxygene.dico.GF_AssociationRole;
035: import fr.ign.cogit.geoxygene.dico.GF_AssociationType;
036: import fr.ign.cogit.geoxygene.dico.GF_AttributeType;
037: import fr.ign.cogit.geoxygene.dico.GF_Constraint;
038: import fr.ign.cogit.geoxygene.dico.GF_FeatureType;
039: import fr.ign.cogit.geoxygene.dico.GF_InheritanceRelation;
040: import fr.ign.cogit.geoxygene.dico.GF_Operation;
041: import fr.ign.cogit.geoxygene.dico.GF_PropertyType;
042:
043: /**
044: * Utilisation du dictionnaire de données : exemple de code.
045: *
046: * @author Thierry Badard & Arnaud Braun
047: * @version 1.1
048: *
049: */
050:
051: /*
052: * On renseigne dans le dico le modele suivant :
053: * Une classe abstraite "entite_adm" (pour entite administrative) ayant 3 attributs :
054: * - nom (String)
055: * - geom (GM_Surface)
056: * - topo (TP_Object)
057: * et 1 operation : getSurface().
058: * Cette classe a 2 classes filles non abstraites : "commune" et "departement".
059: * Il y a 2 associations entre commune et departement : "compose" et "prefecture"
060: * Chacune des associations a 2 roles (= les extremites du lien);
061: * L'association "compose" a une operation : getNumber().
062: * L'association "prefecture" a un attribut : "habitant".
063: * L'attribut "habitant" a lui-meme un attribut : "age_moyen"
064: * L'attribut "geom" a une contrainte : "ct_geom"
065: *
066: * Le programme suivant :
067: * - renseigne le modele : methode creeNouveauxObjets()
068: * - effectue quelques requetes : methode interrogeDico()
069: *
070: */
071:
072: public class TestDico {
073:
074: ///////////////////////////////////////////////////////////////////////////////////////////////////////
075: ///////////////////////////////////////////////////////////////////////////////////////////////////////
076: /* Attributs */
077: private static Geodatabase db;
078:
079: ///////////////////////////////////////////////////////////////////////////////////////////////////////
080: ///////////////////////////////////////////////////////////////////////////////////////////////////////
081: /* Constructeur */
082: public TestDico() {
083: db = GeodatabaseOjbFactory.newInstance();
084: }
085:
086: ///////////////////////////////////////////////////////////////////////////////////////////////////////
087: ///////////////////////////////////////////////////////////////////////////////////////////////////////
088: /* méthode main */
089: public static void main(String args[]) {
090: TestDico test = new TestDico();
091:
092: test.creeNouveauxObjets();
093: test.interrogeDico();
094:
095: }
096:
097: ///////////////////////////////////////////////////////////////////////////////////////////////////////
098: ///////////////////////////////////////////////////////////////////////////////////////////////////////
099: public void creeNouveauxObjets() {
100:
101: // Debut d'une transaction
102: System.out.println("Debut transaction");
103: db.begin();
104:
105: // creation d'un nouveau Feature Type "entite"
106: GF_FeatureType entite = new GF_FeatureType();
107: db.makePersistent(entite); // on le rend persistent
108: entite.setTypeName("entite_adm");
109: entite.setDefinition("Entite administrative");
110: entite.setIsAbstract(true); // abstrait
111:
112: // creation d'un nouvel attribut "nom" sur entite
113: GF_AttributeType nom = new GF_AttributeType();
114: db.makePersistent(nom); // on le rend persistent
115: nom.setMemberName("nom");
116: nom.setDefinition("Nom de l'entite administrative");
117: nom.setValueType("String");
118: nom.setCardMin(1);
119: nom.setCardMax(1);
120: entite.addProperty(nom); // on ajoute nom a la liste des attributs de entite
121: // remarque : tel qu'est code le dico,
122: // "entite.addProperty(nom)" execute automatiquement "nom.setFeatureType(entite)"
123:
124: // creation d'un nouvel attribut "geom" sur entite
125: GF_AttributeType geom = new GF_AttributeType();
126: db.makePersistent(geom); // on le rend persistent
127: geom.setMemberName("geom");
128: geom.setDefinition("Geometrie de l'entite administrative");
129: geom.setValueType("GM_Surface");
130: geom.setCardMin(1);
131: geom.setCardMax(3); // peut avoir jusqu'a 3 geometries (multirepresentation)
132: entite.addProperty(geom);
133:
134: // creation d'un nouvel attribut "topo" sur entite
135: GF_AttributeType topo = new GF_AttributeType();
136: db.makePersistent(topo); // on le rend persistent
137: topo.setMemberName("topo");
138: topo.setDefinition("Topologie de l'entite administrative");
139: topo.setValueType("TP_Object");
140: topo.setCardMin(0); // on n'est pas oblige de fournir une topologie
141: topo.setCardMax(1);
142: entite.addProperty(topo);
143:
144: // creation d'une operation "getSurface" sur entite
145: GF_Operation op = new GF_Operation();
146: db.makePersistent(op); // on le rend persistent
147: op.setMemberName("getSurface");
148: op
149: .setDefinition("Renvoie la valeur de la surface de l'entite administrative");
150: op
151: .setSignature("entite_adm.getSurface(unit : UnitOfMeasure) : int");
152: entite.addProperty(op); // meme remarque que pour un attribut : executer automatiquement "op.setFeatureType(entite)"
153:
154: // creation d'un nouveau Feature Type "departement"
155: GF_FeatureType dept = new GF_FeatureType();
156: db.makePersistent(dept); // on le rend persistent
157: dept.setTypeName("departement");
158: dept.setDefinition("Departement");
159: dept.setIsAbstract(false); // non abstrait - cette ligne est inutile car est false par defaut
160:
161: // creation d'un nouveau Feature Type "commune"
162: GF_FeatureType commune = new GF_FeatureType();
163: db.makePersistent(commune); // on le rend persistent
164: commune.setTypeName("commune");
165: commune.setDefinition("Commune");
166:
167: // creation d'une relation d'heritage entre "entite" et "dept"
168: GF_InheritanceRelation herite = new GF_InheritanceRelation();
169: db.makePersistent(herite);
170: herite.setName("entite_adm/department");
171: herite
172: .setDescription("Un departement est une entite administrative");
173: herite.setUniqueInstance(true); // une entite_adm est SOIT une commune, SOIT un departement, mais jamais les 2 a la fois
174: dept.addGeneralization(herite); // execute automatiquement "herite.setSubType(dept)
175: entite.addSpecialization(herite); // execute automatiquement "herite.addSuperType(entite)
176:
177: // creation d'une relation d'heritage entre "entite" et "commune"
178: herite = new GF_InheritanceRelation(); // on re-utilise et on re-instancie l'objet "herite" qui a deja ete dclare
179: db.makePersistent(herite);
180: herite.setName("entite_adm/commune");
181: herite
182: .setDescription("Une commune est une entite administrative");
183: herite.setUniqueInstance(true); // une entite_adm est SOIT une commune, SOIT un departement, mais jamais les 2 a la fois
184: commune.addGeneralization(herite);
185: entite.addSpecialization(herite);
186:
187: // creation d'une association "prefecture" entre commune et departement
188: GF_AssociationType prefecture = new GF_AssociationType();
189: db.makePersistent(prefecture);
190: prefecture.setTypeName("prefecture");
191: prefecture.setDefinition("Prefecture d'un departement");
192: prefecture.addLinkBetween(commune);
193: prefecture.addLinkBetween(dept);
194:
195: // creation d'un attribut "habitant" sur l'association pour donner le nombre d'habitants de la prefecture
196: // ceci est permis car GF_AssociationType herite de GF_FeatureType
197: GF_AttributeType hab = new GF_AttributeType();
198: db.makePersistent(hab);
199: hab.setMemberName("habitants");
200: hab.setDefinition("Nombre d'habitants de la prefecture");
201: hab.setValueType("int");
202: hab.setCardMin(1);
203: hab.setCardMax(1);
204: prefecture.addProperty(hab);
205:
206: // creation du role "est prefecture de " sur commune
207: GF_AssociationRole est_pref_de = new GF_AssociationRole();
208: db.makePersistent(est_pref_de);
209: est_pref_de.setMemberName("est_prefecture_de");
210: est_pref_de.setDefinition("La commune est prefecture de ");
211: est_pref_de.setValueType("departement");
212: est_pref_de.setCardMin(1);
213: est_pref_de.setCardMax(1);
214: commune.addProperty(est_pref_de); // execute automatiquement "est_pref_de.setFeatureType(commune)
215: prefecture.addRole(est_pref_de); // execute automatiquement "est_pref_de.setAssociationType(prefecture)
216:
217: // creation du role " a pour prefecture " sur departement
218: GF_AssociationRole a_pour_pref = new GF_AssociationRole();
219: db.makePersistent(a_pour_pref);
220: a_pour_pref.setMemberName("a_pour_prefecture");
221: a_pour_pref.setDefinition("Le departement a pour prefecture");
222: a_pour_pref.setValueType("commune");
223: a_pour_pref.setCardMin(1);
224: a_pour_pref.setCardMax(1);
225: dept.addProperty(a_pour_pref); // execute automatiquement "a_pour_pref.setFeatureType(dept)
226: prefecture.addRole(a_pour_pref); // execute automatiquement "a_pour_pref.setAssociationType(prefecture)
227:
228: // creation d'une association "compose" entre commune et departement
229: GF_AssociationType compose = new GF_AssociationType();
230: db.makePersistent(compose);
231: compose.setTypeName("compose");
232: compose.setDefinition("Communes composant un departement");
233: compose.addLinkBetween(commune);
234: compose.addLinkBetween(dept);
235:
236: // creation d'une operation "getNumber" sur "compose"
237: // ceci est permis car GF_AssociationType herite de GF_FeatureType
238: op = new GF_Operation();
239: db.makePersistent(op);
240: op.setMemberName("getNumber");
241: op
242: .setDefinition("Renvoie le nombre de communes constituant le departement");
243: op.setSignature("compose.getNumber() : int");
244: compose.addProperty(op); // meme remarque que pour un attribut : executer automatiquement "op.setFeatureType(compose)"
245:
246: // creation du role "compose" sur commune
247: GF_AssociationRole compose_ = new GF_AssociationRole();
248: db.makePersistent(compose_);
249: compose_.setMemberName("compose_");
250: compose_.setDefinition("La commune compose");
251: compose_.setValueType("departement");
252: compose_.setCardMin(1);
253: compose_.setCardMax(1);
254: commune.addProperty(compose_);
255: compose.addRole(compose_);
256:
257: // creation du role " est_compose_de " sur departement
258: GF_AssociationRole est_compose_de = new GF_AssociationRole();
259: db.makePersistent(est_compose_de);
260: est_compose_de.setMemberName("est_compose_de");
261: est_compose_de.setDefinition("Le departement est compose de");
262: est_compose_de.setValueType("commune");
263: est_compose_de.setCardMin(1);
264: est_compose_de.setCardMax(1000); // au plus 1000 communes dans un departement
265: dept.addProperty(est_compose_de);
266: compose.addRole(est_compose_de);
267:
268: // creation d'une contrainte "ct_geom" sur l'attribut "geom"
269: GF_Constraint ct_geom = new GF_Constraint();
270: db.makePersistent(ct_geom);
271: ct_geom.setDescription("bla bla");
272: geom.addConstraint(ct_geom);
273:
274: // creation d'un attribut "age_moyen" sur "habitant"
275: GF_AttributeType age = new GF_AttributeType();
276: db.makePersistent(age);
277: age.setMemberName("age_moyen");
278: age.setDefinition("Age moyen des habitants");
279: age.setValueType("int");
280: age.setCardMin(1);
281: age.setCardMax(1);
282: age.setCharacterize(hab);
283:
284: // Commit
285: System.out.println("Commit");
286: db.commit();
287:
288: }
289:
290: ///////////////////////////////////////////////////////////////////////////////////////////////////////
291: ///////////////////////////////////////////////////////////////////////////////////////////////////////
292: public void interrogeDico() {
293:
294: // inutile d'ouvrir une transaction ici,
295: // car on ne cree pas de nouvelles données persistantes
296:
297: // Chargement d'un objet par son nom - requete OQL
298: String query = "select x from dico.GF_FeatureType where typeName=$1";
299: String parametre = "entite_adm";
300: List results = db.loadOQL(query, parametre);
301: Iterator it = results.iterator();
302: // On parcourt le resultat de la requete (un seul resultat ici !)
303: while (it.hasNext()) {
304: GF_FeatureType ft1 = (GF_FeatureType) it.next();
305: System.out.println("identifiant de l'objet chargé : "
306: + ft1.getId());
307: System.out.println("nom de l'objet chargé : "
308: + ft1.getTypeName());
309: System.out.println("nombre de sous-classes : "
310: + ft1.sizeSpecialization());
311: if (ft1.sizeSpecialization() > 0)
312: for (int i = 0; i < ft1.sizeSpecialization(); i++) {
313: GF_InheritanceRelation rel = (GF_InheritanceRelation) ft1
314: .getSpecialization().get(i);
315: System.out.println("heritage - classe fille :"
316: + rel.getSubType().getTypeName());
317: }
318: System.out.println("nombre de proprietes : "
319: + ft1.sizeProperties());
320: if (ft1.sizeProperties() > 0)
321: for (int i = 0; i < ft1.sizeProperties(); i++) {
322: GF_PropertyType attr = (GF_PropertyType) ft1
323: .getProperties().get(i);
324: System.out.println("propriete - "
325: + attr.getMemberName() + " : "
326: + attr.getDefinition());
327: }
328: }
329:
330: System.out.println("");
331:
332: // Chargement d'un objet par son nom - requete OQL
333: query = "select x from dico.GF_FeatureType where typeName=$1";
334: parametre = "commune";
335: results = db.loadOQL(query, parametre);
336: it = results.iterator();
337: // On parcourt le resultat de la requete (un seul resultat ici !)
338: while (it.hasNext()) {
339: GF_FeatureType ft1 = (GF_FeatureType) it.next();
340: System.out.println("identifiant de l'objet chargé : "
341: + ft1.getId());
342: System.out.println("nom de l'objet chargé : "
343: + ft1.getTypeName());
344: System.out.println("nombre de sous-classes : "
345: + ft1.sizeSpecialization());
346: System.out.println("nombre de classes meres : "
347: + ft1.sizeGeneralization());
348: // on remarque qu'on ne retrouve pas toutes les proprietes par heritages !
349: System.out.println("nombre de proprietes : "
350: + ft1.sizeProperties());
351: System.out.println("nombre d'associations : "
352: + ft1.sizeMemberOf());
353: if (ft1.sizeMemberOf() > 0)
354: for (int i = 0; i < ft1.sizeMemberOf(); i++) {
355: GF_AssociationType asso = (GF_AssociationType) ft1
356: .getMemberOf().get(i);
357: System.out.println("association - "
358: + asso.getTypeName() + " : "
359: + asso.getDefinition());
360: System.out.println("nombre de roles - "
361: + asso.sizeRoles());
362: for (int j = 0; j < asso.sizeRoles(); j++) {
363: GF_AssociationRole role = (GF_AssociationRole) asso
364: .getRoles().get(j);
365: System.out.println(" role - "
366: + role.getMemberName() + " : "
367: + role.getDefinition());
368: }
369: }
370: }
371:
372: }
373:
374: }
|