1 /******************************************************************
2 JADE - Java Agent DEvelopment Framework is a framework to develop
3 multi-agent systems in compliance with the FIPA specifications.
4 Copyright (C) 2000 CSELT S.p.A.
5
6 GNU Lesser General Public License
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation,
11 version 2.1 of the License.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22 *****************************************************************/
23
24
25 package sl;
26
27 import java.lang.reflect.*;
28 import java.util.*;
29 import java.io.BufferedWriter;
30 import java.io.BufferedReader;
31 import java.io.IOException;
32 import java.text.*;
33
34
35
36 /***
37 A simple implementation of the <code>Ontology</code> interface. Instances of
38 this class keeps all the ontology data in memory, and don't support an
39 external archive format.
40
41 @author Giovanni Rimassa - Universita` di Parma
42 @version $Date: 2003/10/09 13:00:37 $ $Revision: 1.1.1.1 $
43 */
44 public final class DefaultOntology implements Ontology {
45
46 private Map schemas;
47 private Map roleClasses;
48
49 /***
50 Default constructor.
51 */
52 public DefaultOntology() {
53 schemas = new HashMap();
54 roleClasses = new HashMap();
55 }
56
57
58
59
60 FrameSchema lookupSchema(String name) {
61 return (FrameSchema)schemas.get(new CaseInsensitiveString(name));
62 }
63
64
65 /***
66 Adds a new role to this ontology, without a user defined Java class to
67 represent it.
68 @see jade.onto.Ontology#addRole(String roleName, SlotDescriptor[] slots)
69 */
70 public void addRole(String roleName, SlotDescriptor[] slots) throws OntologyException {
71
72 if (lookupSchema(roleName) != null)
73 throw new OntologyException("A role with name \""+roleName+"\" already exists in the ontology");
74
75
76 FrameSchema fs = new FrameSchema(this, roleName);
77
78 for(int i = 0; i < slots.length; i++) {
79 String n = slots[i].getName();
80 if(n.length() == 0)
81 slots[i].setName(Frame.UNNAMEDPREFIX+ "_"+i);
82 fs.addSlot(slots[i]);
83 }
84
85 addSchemaToTable(roleName, fs);
86
87 }
88
89 /***
90 Adds a new role to this ontology, with a user defined Java class to
91 represent it.
92 @see jade.onto.Ontology#addRole(String roleName, SlotDescriptor[] slots, Class c)
93 */
94 public void addRole(String roleName, SlotDescriptor[] slots, Class newClass) throws OntologyException {
95
96 if (roleClasses.containsValue(newClass))
97 throw new OntologyException("The class \""+newClass.getName()+"\" already represents a role in this ontology");
98
99 addRole(roleName, slots);
100
101 checkClass(roleName, newClass);
102 roleClasses.put(new CaseInsensitiveString(roleName), newClass);
103 }
104
105 /***
106 Adds to this ontology all roles included into another ontology
107 @param o The <code>Ontology</code> object whose roles will
108 be added
109 @see jade.onto.Ontology#joinOntology(Ontology o)
110 */
111 public void joinOntology(Ontology o) throws OntologyException {
112
113 for (Iterator i=o.getVocabulary().iterator(); i.hasNext(); ) {
114
115 String name = (String) i.next();
116 SlotDescriptor[] slots = o.getSlots(name);
117 Class c = o.getClassForRole(name);
118 if (c != null)
119 addRole(name, slots, c);
120 else
121 addRole(name, slots);
122 }
123 }
124
125
126 /***
127 Creates a List of Java objects from the given list of frame.
128 @see jade.onto.Ontology#createObject(List v)
129 */
130 public List createObject(List v) throws OntologyException {
131 List outvec = new ArrayList();
132 for (int i=0; i<v.size(); i++)
133 outvec.add(createSingleObject( (Frame)v.get(i) ));
134 return outvec;
135 }
136
137
138
139
140
141 private Object createSingleObject(Frame f) throws OntologyException {
142
143 String roleName = f.getName();
144 Class c = getClassForRole(roleName);
145 if(c == null)
146 throw new OntologyException("No class able to represent " + roleName + " role. Check the definition of the ontology.");
147
148 Object o = create(f);
149 return initObject(f, o, c);
150 }
151
152 /***
153 Creates a frame from a given Java Object representing an instance of
154 a given role.
155 @see jade.onto.Ontology#createFrame(Object o, String roleName)
156 */
157 public Frame createFrame(Object o, String roleName) throws OntologyException {
158 Class theRoleClass = getClassForRole(roleName);
159 if (theRoleClass == null)
160 throw new OntologyException("No class able to represent " + roleName + " role. Check the definition of the ontology.");
161 if(!theRoleClass.isInstance(o))
162 throw new OntologyException("The object <" + o + "> is not an instance of " + theRoleClass.getName() + " class.");
163
164 FrameSchema fs = lookupSchema(roleName);
165 if(fs == null)
166 throw new OntologyException("Internal error: inconsistency between schema and class table");
167
168
169
170 Frame f = new Frame(roleName);
171 buildFromObject(f, fs, o, theRoleClass);
172
173 return f;
174 }
175
176 /***
177 Checks whether a given frame is correct with respect to this ontology.
178 @see jade.onto.Ontology#check(Frame f)
179 */
180 public void check(Frame f) throws OntologyException {
181 String roleName = f.getName();
182 FrameSchema fs = lookupSchema(roleName);
183 fs.checkAgainst(f);
184 }
185
186 /***
187 Checks whether a given Java object is correct with respect to the given role
188 in this ontology.
189 @see jade.onto.Ontology#check(Object o, String roleName)
190 */
191 public void check(Object o, String roleName) throws OntologyException {
192
193
194
195
196
197
198
199 Class theRoleClass = getClassForRole(roleName);
200 if (theRoleClass == null)
201 throw new OntologyException("No class able to represent " + roleName + " role.");
202 if(!theRoleClass.isInstance(o))
203 throw new OntologyException("The object is not an instance of " + theRoleClass.getName() + " class.");
204
205 FrameSchema fs = lookupSchema(roleName);
206 Iterator it = fs.subSchemas();
207
208 while(it.hasNext()) {
209 SlotDescriptor desc = (SlotDescriptor)it.next();
210 Method m = findMethodCaseInsensitive("get" + translateName(desc.getName()), theRoleClass);
211 try {
212 Object value = m.invoke(o, new Object[] { });
213
214 if(!desc.isOptional() && (value == null))
215 throw new OntologyException("The given object has a 'null' value for the mandatory term " + desc.getName());
216
217 if(desc.isComplex() || desc.isSet())
218 check(value, desc.getType());
219 }
220 catch(InvocationTargetException ite) {
221 String msg = ite.getTargetException().getMessage();
222 throw new OntologyException("Internal error: a reflected method threw an exception.\nMessage was " + msg);
223 }
224 catch(IllegalAccessException iae) {
225 throw new OntologyException("Internal error: the required method is not accessible [" + iae.getMessage() + "]");
226 }
227 catch(SecurityException se) {
228 throw new OntologyException("Wrong class: some required method is not accessible.");
229 }
230 }
231 }
232
233 /***
234 Checks whether a given string is the name of a role in this ontology.
235 @see jade.onto.Ontology#isRole(String roleName)
236 */
237 public boolean isRole(String roleName) throws OntologyException {
238 FrameSchema fs = lookupSchema(roleName);
239 return (fs != null);
240 }
241
242 /***
243 Get the descriptions for all the slots that define the structure of a given
244 ontological role.
245 @see jade.onto.Ontology#getSlots(String roleName)
246 */
247 public SlotDescriptor[] getSlots(String roleName) throws OntologyException {
248 FrameSchema fs = lookupSchema(roleName);
249 return fs.slotsArray();
250 }
251
252 /***
253 @return the name of the role represented by the passed class as
254 registered in this ontology
255 @throws OntologyException if no role is found for this class
256 @see jade.onto.Ontology#getRoleName(Class c)
257 **/
258 public String getRoleName(Class c) throws OntologyException{
259 for (Iterator i=roleClasses.entrySet().iterator(); i.hasNext(); ) {
260 Map.Entry elem = (Map.Entry)i.next();
261 if (c.equals((Class)elem.getValue()))
262 return ((CaseInsensitiveString)elem.getKey()).toString();
263 }
264
265 throw new OntologyException("No rolename registered in this ontology for class "+c.getName());
266 }
267
268 /***
269 @return a <code>List</code> including the names of all the roles
270 in the ontology, i.e. the Vocabulary used by the ontology
271 @see jade.onto.Ontology#getVocabulary()
272 **/
273 public List getVocabulary(){
274
275
276 List vocabulary = new ArrayList();
277 Iterator i = schemas.keySet().iterator();
278 while (i.hasNext()){
279 String roleNameAsString = ((CaseInsensitiveString) (i.next())).toString();
280 vocabulary.add(roleNameAsString);
281 }
282 return vocabulary;
283 }
284
285
286
287
288
289 /***
290 Provides the Java class associated with this ontological role. This class is
291 usually the class used by the <code>create()</code> method to instantiate
292 objects. A useful technique is returning an interface or an abstract class,
293 while using concrete subclasses to create objects.
294 @param a string representing the name of the ontological role
295 @return the Java class that plays this ontological role (e.g. <code>DFAgentDescription.class</code>
296 */
297 public Class getClassForRole(String roleName) {
298 return (Class) roleClasses.get(new CaseInsensitiveString(roleName));
299 }
300
301
302
303
304
305 /***
306 * if name starts with UNNAMED_PREFIX, it removes it
307 * @return the name of a method, given the name of a slot
308 */
309 private String translateName(String name) {
310 StringBuffer buf;
311 if (name.startsWith(Frame.UNNAMEDPREFIX))
312 buf = new StringBuffer(name.substring(Frame.UNNAMEDPREFIX.length()));
313 else
314 buf = new StringBuffer(name);
315 for(int i = 0; i < buf.length(); i++) {
316 char c = buf.charAt(i);
317 switch(c) {
318 case ':':
319 buf.deleteCharAt(i);
320 --i;
321 break;
322 case '-':
323 buf.deleteCharAt(i);
324 buf.setCharAt(i, Character.toUpperCase(buf.charAt(i)));
325 --i;
326 break;
327 }
328 }
329
330 return new String(buf);
331 }
332
333
334 private Class checkGetAndSet(String name, Class c) throws OntologyException {
335 Class result;
336 Method getMethod = findMethodCaseInsensitive("get" + name, c);
337 Method setMethod = findMethodCaseInsensitive("set" + name, c);
338
339
340 Class[] getParams = getMethod.getParameterTypes();
341 if(getParams.length > 0)
342 throw new OntologyException("Wrong class: method " + getMethod.getName() + "() must take no arguments.");
343
344
345 result = getMethod.getReturnType();
346
347 Class[] setParams = setMethod.getParameterTypes();
348 if((setParams.length != 1) || (!setParams[0].equals(result)))
349 throw new OntologyException("Wrong class: method " + setMethod.getName() + "() must take a single argument of type " + result.getName() + ".");
350 Class setReturn = setMethod.getReturnType();
351 if(!setReturn.equals(Void.TYPE))
352 throw new OntologyException("Wrong class: method " + setMethod.getName() + "() must return void.");
353
354 return result;
355
356 }
357
358 /***
359 * @return the number of arguments of the method m
360 */
361 private int getArgumentLength(Method m) {
362 Class[] getParams = m.getParameterTypes();
363 return getParams.length;
364 }
365
366 /***
367 @ return the Class of the return type of the method m
368 */
369 private Class getReturnType(Method m) {
370 return m.getReturnType();
371 }
372
373 /***
374 @ return the Class of the argument type number no. of the method m
375 */
376 private Class getArgumentType(Method m, int no) {
377 Class[] setParams = m.getParameterTypes();
378 return setParams[no];
379 }
380
381 /***
382 * This method checks for correct get and set methods for the
383 * current descriptor and retrieves the implementation type.
384 * This check is for slots of category SET_SLOT or SEQUENCE_SLOT.
385 * <p>
386 * For every <code>SlotDescriptor</code>
387 * of category <code>SET_SLOT</code> or <code>SEQUENCE_SLOT</code>
388 * and named <code>XXX</code>, with elements of type <code>T</code>, the
389 * class must have two accessible methods, with the following
390 * signature:</i>
391 * <ul>
392 * <li> <code>Iterator getAllXXX()</code>
393 * <li> <code>void addXXX(T t)</code>
394 * </ul>
395 */
396 private Class checkGetAndSet2(String name, Class c) throws OntologyException {
397 Method getMethod = findMethodCaseInsensitive("getAll" + name, c);
398 Method addMethod = findMethodCaseInsensitive("add" + name, c);
399
400
401 Class result = getArgumentType(addMethod,0);
402
403
404
405
406 if (getArgumentLength(getMethod) != 0)
407 throw new OntologyException("Wrong class: method " + getMethod.getName() + "() must take no arguments.");
408 if (!getReturnType(getMethod).equals(java.util.Iterator.class))
409 throw new OntologyException("Wrong class: method " + getMethod.getName() + "() must return a java.util.Iterator." + getReturnType(getMethod).toString());
410
411
412 if (getArgumentLength(addMethod) != 1)
413 throw new OntologyException("Wrong class: method " + addMethod.getName() + "() must take one argument.");
414 if (!getArgumentType(addMethod,0).equals(result))
415 throw new OntologyException("Wrong class: method " + addMethod.getName() + "() has the wrong argument type.");
416 if (!getReturnType(addMethod).equals(Void.TYPE))
417 throw new OntologyException("Wrong class: method " + addMethod.getName() + "() must return a void.");
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433 return result;
434
435 }
436
437 private void checkClass(String roleName, Class c) throws OntologyException {
438
439 FrameSchema fs = lookupSchema(roleName);
440 if(fs == null)
441 throw new OntologyException("No schema was found for " + roleName + "role.");
442
443 Iterator it = fs.subSchemas();
444
445
446 while(it.hasNext()) {
447 SlotDescriptor desc = (SlotDescriptor)it.next();
448
449 String slotName = translateName(desc.getName());
450 try {
451
452
453 Class implType;
454
455 if (desc.isSet())
456 implType = checkGetAndSet2(slotName, c);
457 else
458 implType = checkGetAndSet(slotName, c);
459
460
461
462
463
464 if(desc.isComplex() || desc.isSet()) {
465 Class complex = getClassForRole(desc.getType());
466 if (complex != null) {
467
468 if(!implType.isAssignableFrom(complex))
469 throw new OntologyException("Wrong class: the " + desc.getName() + " role is represented by " + complex + " class, which is not a subtype of " + implType + " class.");
470 }
471 } else {
472 Class slotType = null;
473 try {
474 slotType = Class.forName(desc.getType());
475
476 if(!implType.isAssignableFrom(slotType))
477 throw new OntologyException("1 Wrong class: the primitive slot " + desc.getName() + " is of type "+ implType + ", but must be a subtype of " + slotType + ".");
478 }
479 catch (Exception e) {
480
481
482
483 try{
484 String type = desc.getType();
485 Class componentImplType = implType.getComponentType();
486 if (type.endsWith("[]") && componentImplType != null){
487 String componentType = type.substring(0, type.length() - 2);
488 slotType = Class.forName(componentType);
489 if (!componentImplType.isAssignableFrom(slotType))
490 throw new OntologyException("2 Wrong class: the primitive slot " + desc.getName() + " is of type "+ componentImplType + "[], but must be a subtype of " + slotType + "[].");
491 }
492 else
493 throw new OntologyException("3 Wrong class: the primitive slot " + desc.getName() + " is of type "+ implType + ", but must be a subtype of " + slotType + ".");
494 }
495 catch (Exception e1) {
496 throw new OntologyException("4 Wrong class: the primitive slot " + desc.getName() + " is of type "+ implType + ", but must be a subtype of " + desc.getType() + ".");
497 }
498 }
499 }
500 }
501 catch(SecurityException se) {
502 throw new OntologyException("Wrong class: some required method is not accessible.");
503 }
504
505 }
506
507 }
508
509
510 private Object initObject(Frame f, Object entity, Class theRoleClass) throws OntologyException {
511
512 String roleName = f.getName();
513
514 FrameSchema fs = lookupSchema(roleName);
515 Iterator it = fs.subSchemas();
516 int slotPosition = 0;
517
518
519 while(it.hasNext()) {
520 SlotDescriptor desc = (SlotDescriptor)it.next();
521 String slotName = desc.getName();
522 String methodName;
523 if (desc.isSet())
524 methodName = "add" + translateName(slotName);
525 else
526 methodName = "set" + translateName(slotName);
527
528
529 Method setMethod = findMethodCaseInsensitive(methodName, theRoleClass);
530 try {
531 Object slotValue;
532 if (slotName.startsWith(Frame.UNNAMEDPREFIX))
533 slotValue = f.getSlot(slotPosition);
534 else
535 slotValue = f.getSlot(slotName);
536
537
538
539
540 if(desc.isComplex()) {
541 slotValue = createSingleObject((Frame)slotValue);
542 setMethod.invoke(entity, new Object[] { slotValue });
543 }
544
545
546 else if (desc.isSet()) {
547 Frame set = (Frame) slotValue;
548 if (desc.getType().equalsIgnoreCase(Ontology.ANY_TYPE)){
549 for (int i=0; i<set.size(); i++) {
550 try {
551 Object element = createSingleObject((Frame)set.getSlot(i));
552 setMethod.invoke(entity, new Object[]{element});
553 }
554 catch (Exception ee1) {
555
556 setMethod.invoke(entity, new Object[]{set.getSlot(i)});
557 }
558 }
559 }
560 else if (desc.hasPrimitiveType()) {
561 for (int i=0; i<set.size(); i++)
562 setMethod.invoke(entity, new Object[]{ castPrimitiveValue(set.getSlot(i), desc.getType())});
563 }
564 else {
565 for (int i=0; i<set.size(); i++) {
566 Object element = createSingleObject((Frame)set.getSlot(i));
567 setMethod.invoke(entity, new Object[]{element});
568 }
569 }
570 }
571
572
573
574 else {
575 setMethod.invoke(entity, new Object[] { castPrimitiveValue(slotValue, desc.getType()) });
576 }
577 slotPosition++;
578
579 }
580 catch(Frame.NoSuchSlotException fnsse) {
581 if(!desc.isOptional())
582 throw fnsse;
583 }
584 catch(InvocationTargetException ite) {
585 Throwable e = ite.getTargetException();
586 e.printStackTrace();
587 throw new OntologyException("Internal error: a reflected method threw an exception.\n e.getMessage()",ite);
588 }
589 catch(IllegalAccessException iae) {
590 throw new OntologyException("Internal error: the required method is not accessible [" + iae.getMessage() + "]",iae);
591 }
592 catch(SecurityException se) {
593 throw new OntologyException("Wrong class: some required method is not accessible.",se);
594 }
595 catch(IllegalArgumentException iare){
596 throw new OntologyException("Possible mismatch between the type returned by the parser and the type declared in the ontology [" + iare.getMessage() + "]. For role "+roleName+" and slot "+slotName,iare);
597 }
598 catch(ClassCastException iacce) {
599 throw new OntologyException("Possibly a primitive value has been used instead of a Frame slot",iacce);
600 }
601
602 }
603
604 return entity;
605 }
606
607 private Object castPrimitiveValue(Object value, String type) throws IllegalArgumentException {
608
609
610
611
612
613
614
615
616
617
618
619 String stringifiedValue = value.toString();
620 Object castedValue = null;
621 try{
622 if (type.equalsIgnoreCase(Ontology.INTEGER_TYPE))
623 castedValue = (Object) new Integer(stringifiedValue);
624 else if (type.equalsIgnoreCase(Ontology.SHORT_TYPE))
625 castedValue = (Object) new Short(stringifiedValue);
626 else if (type.equalsIgnoreCase(Ontology.FLOAT_TYPE))
627 castedValue = (Object) new Float(stringifiedValue);
628 else if (type.equalsIgnoreCase(Ontology.CHARACTER_TYPE)){
629 if (stringifiedValue.length() != 1)
630 throw new IllegalArgumentException("Type mismatch for value " + stringifiedValue + " and type " + type);
631 castedValue = (Object) new Character(stringifiedValue.charAt(0));
632 }
633 else if (type.equalsIgnoreCase(Ontology.BYTE_TYPE)){
634 castedValue = (Object) new Byte(stringifiedValue);
635 }
636 else if (type.equalsIgnoreCase(Ontology.STRING_TYPE)){
637 if (!value.getClass().equals(java.lang.Byte[].class))
638 castedValue = stringifiedValue;
639 }
640 else
641 castedValue = value;
642 }
643 catch(NumberFormatException nfe) {
644 throw new IllegalArgumentException("Format mismatch between value " + stringifiedValue + " and type " + type);
645 }
646
647 return castedValue;
648 }
649
650 private void buildFromObject(Frame f, FrameSchema fs, Object o, Class theRoleClass) throws OntologyException {
651 Iterator it = fs.subSchemas();
652 while(it.hasNext()) {
653 SlotDescriptor desc = (SlotDescriptor)it.next();
654 String slotName = desc.getName();
655 String methodName;
656 if (desc.isSet())
657 methodName = "getAll" + translateName(slotName);
658 else
659 methodName = "get" + translateName(slotName);
660
661
662 Method getMethod = findMethodCaseInsensitive(methodName, theRoleClass);
663 try {
664 Object value = getMethod.invoke(o, new Object[] { });
665 if (value == null) {
666 if (!desc.isOptional())
667 throw new OntologyException("Slot "+slotName+" has a null value and it is mandatory");
668 }
669 else {
670
671 if(!desc.isComplex() && !desc.isSet()) {
672 f.putSlot(slotName, value);
673 }
674 else if (desc.isComplex()) {
675
676
677 String roleName = desc.getType();
678 if (roleName.equalsIgnoreCase(Ontology.ANY_TYPE))
679 roleName = getRoleName(value.getClass());
680 f.putSlot(slotName, createFrame(value, roleName));
681 }
682 else if (desc.isSet()) {
683 Frame setFrame;
684 if (desc.getCategory() == Ontology.SET_SLOT)
685 setFrame = new Frame(Ontology.NAME_OF_SET_FRAME);
686 else
687 setFrame = new Frame(Ontology.NAME_OF_SEQUENCE_FRAME);
688 Iterator i = (Iterator)value;
689 if (desc.getType().equalsIgnoreCase(Ontology.ANY_TYPE)) {
690 while (i.hasNext()) {
691 Object elem = i.next();
692 try {
693 setFrame.putSlot(createFrame(elem, getRoleName(elem.getClass())));
694 } catch (Exception e) {
695
696 setFrame.putSlot(elem);
697 }
698 }
699 } else if (desc.hasPrimitiveType())
700 while (i.hasNext())
701 setFrame.putSlot(i.next());
702 else
703 while (i.hasNext())
704 setFrame.putSlot(createFrame(i.next(), desc.getType()));
705 f.putSlot(slotName,setFrame);
706 }
707 }
708 }
709 catch(InvocationTargetException ite) {
710 String msg = ite.getTargetException().getMessage();
711 throw new OntologyException("Internal error: a reflected method threw an exception.\nMessage was " + msg);
712 }
713 catch(IllegalAccessException iae) {
714 throw new OntologyException("Internal error: the required method is not accessible [" + iae.getMessage() + "]");
715 }
716 catch(SecurityException se) {
717 throw new OntologyException("Wrong class: some required method is not accessible.");
718 }
719
720 }
721
722 }
723
724
725 private void addSchemaToTable(String roleName, FrameSchema fs) {
726 schemas.put(new CaseInsensitiveString(roleName), fs);
727 }
728
729
730
731
732 private Method findMethodCaseInsensitive(String name, Class c) throws OntologyException {
733 Method[] methods = c.getMethods();
734 for(int i = 0; i < methods.length; i++) {
735 String ithName = methods[i].getName();
736 if(ithName.equalsIgnoreCase(name))
737 return methods[i];
738 }
739 throw new OntologyException("Method " + name + " not found in class "+c.getName());
740 }
741
742
743 /***
744 * @see Ontology.fromSL0String(String)
745 **/
746 public String fromSL0String(String str) throws CodecException, OntologyException {
747 Ontology meta = JADEMetaOntology.instance();
748 schemas.clear();
749 roleClasses.clear();
750 List l = (new SL0Codec()).decode(str, meta);
751 AnOntology o = (AnOntology)meta.createObject(l).get(0);
752 fromMetaOntologyRepresentation(o);
753 return o.getName();
754 }
755
756 /***
757 @see Ontology.fromMetaOntologyRepresentation(AnOntology)
758 **/
759 public void fromMetaOntologyRepresentation(AnOntology o) throws OntologyException {
760 for (Iterator i=o.getAllRoles(); i.hasNext(); ) {
761 Role r = (Role)i.next();
762 ArrayList slots = new ArrayList();
763 for (Iterator j=r.getAllSlots(); j.hasNext(); ) {
764 Slot s = (Slot)j.next();
765 SlotDescriptor sd;
766 if (s.getName() != null)
767 sd = new SlotDescriptor(s.getName(), s.getCategory().intValue(), s.getType(), s.getPresence().booleanValue());
768 else
769 sd = new SlotDescriptor(s.getCategory().intValue(), s.getType(), s.getPresence().booleanValue());
770 slots.add(sd);
771 }
772 SlotDescriptor[] sdarray = new SlotDescriptor[slots.size()];
773 slots.toArray(sdarray);
774 if (r.getClassName() == null)
775 addRole(r.getName(),sdarray);
776 else
777 try {
778 addRole(r.getName(), sdarray, Class.forName(r.getClassName()));
779 } catch (ClassNotFoundException e) {
780 System.out.println("WARNING: ClassNotFoundException in adding role "+r.getName()+" to the ontology. The role has been then added without any class");
781 addRole(r.getName(), sdarray);
782 }
783 }
784 }
785
786
787 /***
788 * Return a String representing this ontology Object by calling
789 * the method <code>toSL0String()</code> and catching any exception.
790 * Notice that this method ignores the name of the ontology and, therefore,
791 * the method <code>toSL0String()</code> should be preferred, instead.
792 * @return the String representing this ontology, or null if any
793 * exception occurs.
794 **/
795 public String toString() {
796 try {
797 return toSL0String("unknownOntologyName");
798 } catch (OntologyException o) {
799 o.printStackTrace();
800 }
801 return null;
802 }
803
804 /***
805 @see Ontology.toMetaOntologyRepresentation(String)
806 **/
807 public AnOntology toMetaOntologyRepresentation (String ontologyName){
808 AnOntology o = new AnOntology();
809 if ((ontologyName == null) || (ontologyName.trim().equals("")))
810 o.setName("unknownOntologyName");
811 else
812 o.setName(ontologyName);
813
814
815 for (Iterator i=schemas.values().iterator(); i.hasNext(); ) {
816 FrameSchema fs = (FrameSchema) i.next();
817 String roleName = fs.getName();
818 Role r = new Role();
819 r.setName(roleName);
820 Class c = getClassForRole(roleName);
821 if (c != null)
822 r.setClassName(c.getName());
823
824 for (Iterator j = fs.subSchemas(); j.hasNext(); ) {
825 SlotDescriptor dsc = (SlotDescriptor) j.next();
826 Slot s = new Slot();
827
828 if (!(dsc.getName().equals("") || dsc.getName().startsWith(Frame.UNNAMEDPREFIX) ) )
829 s.setName(dsc.getName());
830
831 s.setCategory(new Long(dsc.getCategory()));
832
833 s.setType(dsc.getType());
834
835 s.setPresence(new Boolean(dsc.isOptional()));
836 r.addSlots(s);
837 }
838 o.addRoles(r);
839 }
840 return o;
841 }
842
843 /***
844 Writes the ontology represented by this Ontology object as an
845 SL-0 expression.
846 @see Ontology.toSL0String()
847 */
848 public String toSL0String(String ontologyName) throws OntologyException {
849 AnOntology o = toMetaOntologyRepresentation(ontologyName);
850 Ontology meta = JADEMetaOntology.instance();
851 String s;
852 List l = new ArrayList(1);
853 l.add(meta.createFrame(o, meta.getRoleName(o.getClass())));
854 s = (new SL0Codec()).encode(l, meta);
855 return(s);
856 }
857
858
859
860 public Object create(Frame f) throws OntologyException {
861 try {
862 return getClassForRole(f.getName()).newInstance();
863 } catch (Exception e) {
864 throw new OntologyException(e.getMessage());
865 }
866 }
867
868 }