View Javadoc
1   package eu.simuline.relana.model;
2   
3   import eu.simuline.relana.expressions.FormulaDecl;
4   
5   import java.util.List;
6   //import java.util.ArrayList;
7   import java.util.Set;
8   import java.util.HashSet;
9   import java.util.TreeSet;
10  import java.util.Map;
11  import java.util.HashMap;
12  //import java.util.TreeMap;
13  //import java.util.Iterator;
14  
15  /**
16   * Represents a component class. 
17   * Like a java-class this has a name {@link #cName}, 
18   * a package {@link #pkg} and a superclass {@link #superClass} 
19   * which is again a {@link CClass}. 
20   * As this is a component class, it has named components 
21   * and the mapping from names to components is given by {@link #subComponents}. 
22   * Observe that the values are not {@link CClass}es 
23   * but {@link CClassLink}s as the components may not be resolved 
24   * if this class is resolved 
25   * as a component may be again of this {@link CClass}. **** 
26   * Maps and effects **** are to be explained later. 
27   * <code>x</code>
28   *
29   * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
30   * @version 1.0
31   */
32  public class CClass implements CClassLink {
33  
34      /* -------------------------------------------------------------------- *
35       * inner classes.                                                       *
36       * -------------------------------------------------------------------- */
37  
38      /**
39       * Enumerates the class modifier for an {@link SClass}: 
40       * input and output. 
41       */
42      public enum SClassModifier {
43  
44  	/* ---------------------------------------------------------------- *
45  	 * constructor constants.                                           *
46  	 * ---------------------------------------------------------------- */
47  
48  	INPUT(),
49  	OUTPUT();
50  
51  	/* ---------------------------------------------------------------- *
52  	 * constants and initializer.                                       *
53  	 * ---------------------------------------------------------------- */
54  
55  	/**
56  	 * Maps the names of the modifiers in the ccl-files 
57  	 * to the modifiers: 
58  	 * <ul>
59  	 * <li>
60  	 * <code>input</code>  maps to {@link #INPUT} and 
61  	 * <li>
62  	 * <code>output</code> maps to {@link #OUTPUT}. 
63  	 * </ul>
64  	 */
65  	static final Map<String, SClassModifier> NAME2MOD;
66  
67  	static {
68  	    NAME2MOD = new HashMap<String, SClassModifier>();
69  	    NAME2MOD.put("input",   INPUT);
70  	    NAME2MOD.put("output", OUTPUT);
71  	}
72  
73  	/* ---------------------------------------------------------------- *
74  	 * methods.                                                         *
75  	 * ---------------------------------------------------------------- */
76  
77  	/**
78  	 * Gets the class modifier with the given name. 
79  	 *
80  	 * @param name
81  	 *    one of the names <code>input</code>, <code>output</code>. 
82  	 * @throws IllegalArgumentException
83  	 *    if the modifier is unknown. 
84  	 */
85  	public static SClassModifier get(String name) {
86  	    SClassModifier res = NAME2MOD.get(name);
87  	    if (res == null) {
88  		throw new IllegalArgumentException
89  		    ("Unknown access modifier: \"" + name + "\". ");
90  	    }
91  	    return res;
92  	}
93      } // enum SClassModifier 
94  
95      /**
96       * Represents the declaration of an {@link SClass} 
97       * within this {@link CClass}. 
98       * This comprises optional access modifiers, the class, the name 
99       * and also optionally, a probability distribution {@link #distr} 
100      * or a formula declaration {@link #form}. 
101      */
102     public static final class SClassDecl {
103 
104 	/* ---------------------------------------------------------------- *
105 	 * attributes.                                                      *
106 	 * ---------------------------------------------------------------- */
107 
108 
109 	/**
110 	 * Whether this declaration is a redeclaration. 
111 	 */
112 	private final boolean isRedeclare;
113 
114 	/**
115 	 * The set of modifiers of this effect. 
116 	 */
117 	private final Set<SClassModifier> modifiers;
118 
119 	/**
120 	 * The class of this effect. 
121 	 */
122 	private final SClass sClass;
123 
124 	/**
125 	 * The name of this effect which must be unique 
126 	 * within the keys of {@link #effects}. 
127 	 */
128 	private final String name;
129 
130 	/**
131 	 * An optional probability distribution; otherwise <code>null</code>. 
132 	 */
133 	private final ProbDistr distr;
134 
135 	/**
136 	 * An optional formula declaration; otherwise <code>null</code>. 
137 	 */
138 	private FormulaDecl form;
139 
140 	/* ---------------------------------------------------------------- *
141 	 * constructors.                                                    *
142 	 * ---------------------------------------------------------------- */
143 
144 	/**
145 	 * Creates a new <code>SClassDecl</code> instance without formula.
146 	 *
147 	 * @param isRedeclare 
148 	 *    whether this is a redeclaration. 
149 	 * @param modifiers 
150 	 *    The set of mofifiers of this effect. 
151 	 * @param sClass 
152 	 *    The class of this effect. 
153 	 * @param name 
154 	 *    The name of this effect which must be unique 
155 	 *    within the keys of {@link #effects}. 
156 	 * @param distr 
157 	 *    An optional probability distribution; 
158 	 *    otherwise <code>null</code>. 
159 	 * @throws IllegalArgumentException
160 	 *    for inputs no probability distribution must be provided. 
161 	 * @see #setFormula
162 	 */
163 	public SClassDecl(boolean isRedeclare,
164 			  Set<SClassModifier> modifiers,
165 			  SClass sClass,
166 			  String name,
167 			  ProbDistr distr) {
168 	    this.isRedeclare = isRedeclare;
169 	    this.modifiers = modifiers;
170 	    this.sClass = sClass;
171 	    this.name = name;
172 	    // **** the latter maybe should be part of verification process. 
173 	    this.distr = distr;
174 	    if (isInput() && (this.distr != null)) {
175 		throw new IllegalArgumentException
176 		    ("SClass " + name + " is declared as input " + 
177 		     "and at the same time a probability distribution " + 
178 		     "is attached. ");
179 	    }
180 	}
181 
182 	/* ---------------------------------------------------------------- *
183 	 * methods.                                                         *
184 	 * ---------------------------------------------------------------- */
185 
186 	/**
187 	 * Sets the given formula <code>form</code> and checks consistency; 
188 	 * may throw various exceptions. 
189 	 *
190 	 * @param form 
191 	 *    a <code>FormulaDecl</code> which may also be <code>null</code>. 
192 	 * @throws IllegalArgumentException
193 	 *    if <code>form != null</code> and at the same time 
194 	 *    <ul>
195 	 *    <li>
196 	 *    this effect is declared as input or 
197 	 *    <li>
198 	 *    this effect has a probability distribution already. 
199 	 *    <li>
200 	 *    the formula is not assignment compatible 
201 	 *    which currently means the types do not coincide. 
202 	 *    </ul>
203 	 */
204 	public void setFormula(FormulaDecl form) {
205 	    this.form = form;
206 	    if (isInput() && (this.form != null)) {
207 		throw new IllegalArgumentException
208 		    ("SClass " + name + " is declared as input " + 
209 		     "and at the same time a formula is attached. ");
210 	    }
211 
212 	    if ((this.distr != null) && (this.form != null)) {
213 		throw new IllegalArgumentException
214 		    ("Either a probability distribution may be given " + 
215 		     "or a formula but not both. ");
216 	    }
217 
218 	    // here, one may consider 
219 	    // a weaker form of assignment compatibility ****
220 	    if ((this.form != null) && 
221 		!this.form.retType().equals(this.sClass.getType())) {
222 		throw new IllegalArgumentException
223 		    ("Tried to assign formula \"" + this.form + 
224 		     "\" with return type " + this.form.retType() + 
225 		     " to variable \"" + this.name + 
226 		     "\" with type " + this.sClass.getType() + 
227 		     " which is not assignment compatible. ");
228 	    }
229 	}
230 
231 	public SClass getSClass() {
232 	    return this.sClass;
233 	}
234 
235 	public String getName() {
236 	    return this.name;
237 	}
238 
239 	/**
240 	 * Returns whether this effect is declared as input. 
241 	 *
242 	 * @return 
243 	 *    whether this effect is declared as input. 
244 	 */
245 	public boolean isInput() {
246 	    return this.modifiers.contains(SClassModifier.INPUT);
247 	}
248 
249 	/**
250 	 * Returns whether this effect is declared as output. 
251 	 *
252 	 * @return 
253 	 *    whether this effect is declared as output. 
254 	 */
255 	public boolean isOutput() {
256 	    return this.modifiers.contains(SClassModifier.OUTPUT);
257 	}
258 
259 	/**
260 	 * Returns whether this is a redeclaration. 
261 	 *
262 	 * @return 
263 	 *    whether this is a redeclaration. 
264 	 */
265 	public boolean isRedeclare() {
266 	    return this.isRedeclare;
267 	}
268 
269 	/**
270 	 * Returns the probability distribution if any; 
271 	 * otherwise <code>null</code>. 
272 	 *
273 	 * @return 
274 	 *    {@link #distr}. 
275 	 */
276 	ProbDistr getProbDistr() {
277 	    return this.distr;
278 	}
279 
280 	/**
281 	 * Returns the formula if any; otherwise <code>null</code>. 
282 	 *
283 	 * @return 
284 	 *    {@link #form}. 
285 	 */
286 	FormulaDecl getFormulaDecl() {
287 	    return this.form;
288 	}
289 
290 	/**
291 	 * Returns a effect according to this declaration. 
292 	 *
293 	 * @return 
294 	 *    a effect according to this declaration. 
295 	 *    This depends on the class, the probability distribution 
296 	 *    and the name but not on the modifiers and the formula. 
297 	 */
298 	SInstance getSInstance() {
299 	    return new SInstance(getSClass().getType(),
300 				 getProbDistr(),
301 				 getName());
302 	}
303 
304 	public String toString() {
305 	    StringBuffer res = new StringBuffer();
306 	    res.append('\n');
307 	    if (this.isRedeclare) {
308 		res.append("redeclare");
309 	    }
310 
311 	    res.append(this.modifiers);
312 	    res.append(getSClass().getName());
313 	    res.append(getName());
314 	    if (this.distr != null) {
315 		res.append(" distr: ");
316 		res.append(this.distr.toString());
317 	    }
318 
319 	    if (this.form != null) {
320 		res.append(" formula: ");
321 		res.append(this.form.toString());
322 	    }
323 	    return res.toString();
324 	}
325 
326 	// for use in hash sets/maps 
327 	public boolean equals(Object obj) {
328 	    return super.equals(obj);
329 	}
330 
331 	// for use in hash sets/maps 
332 	public int hashCode() {
333 	    return super.hashCode();
334 	}
335 
336     } // class SClassDecl 
337 
338     /* -------------------------------------------------------------------- *
339      * constants.                                                           *
340      * -------------------------------------------------------------------- */
341 
342     /**
343      * The root of the subclass hierarchy of {@link CClass}es: 
344      * Class named <code>Component</code> without superclass, 
345      * i.e. {@link #getSuperClass()} returns <code>null</code>
346      * This represents an empty component. 
347      */
348     public static final CClass COMPONENT = 
349     new CClass("Component",
350 	       Package.BUILD_IN,
351 	       null, // superclass.. the only with null
352 	       new HashMap<String, MapDecl>(),
353 	       new HashMap<String, CClassLink>(),
354 	       new HashMap<String, CClass.SClassDecl>()) {
355 
356 	// overrides all methods based on getSuperClass() != null 
357 
358 	// maybe there should be an exception ****
359 	@Override
360 	public MapDecl getMapDecl(String name) {
361 	    return null;
362 	}
363 	// maybe there should be an exception ****
364 	@Override
365 	public CClassLink getComponentCls(String name) {
366 	    return null;
367 	}
368 	// maybe there should be an exception ****
369 	@Override
370 	public SClassDecl getEffectDecl(String name) {
371 	    return null;
372 	}
373 	@SuppressWarnings("PMD.SingletonClassReturningNewInstance")
374 	@Override
375 	public CInstance getInstance() {
376 	    return new CInstance();
377 	}
378 	@Override
379 	Set<String> getComponentNames() {
380 	    return new TreeSet<String>();
381 	}
382 	@Override
383 	Set<String> getEffectNames() {
384 	    return new TreeSet<String>();
385 	}
386 	@Override
387 	void verify() throws VerifyException {
388 	    // is empty. 
389 	}
390     };
391 
392     /* -------------------------------------------------------------------- *
393      * attributes.                                                          *
394      * -------------------------------------------------------------------- */
395 
396     /**
397      * The Name of this <code>CClass</code>. 
398      */
399     private final String cName;
400 
401     /**
402      * The package of this class. 
403      */
404     private final Package pkg;
405 
406     /**
407      * The unique superclass of this class. 
408      * There is exactly one class without super class: 
409      * {@link #COMPONENT} and the only one 
410      * for which this field ist <code>null</code>. 
411      */
412     private final CClass superClass;
413 
414     /**
415      * The maps declared in this class. 
416      */
417     private final Map<String, MapDecl> maps;
418 
419     /**
420      * Maps the names of the subcomponents to their classes. 
421      */
422     private final Map<String, CClassLink> subComponents;
423 
424     /**
425      * Maps the names of the effects to their classes. 
426      */
427     private final Map<String, SClassDecl> effects;
428 
429     /**
430      * The location of the description of this class within the library. 
431      */
432     //private ClassLocator loc;
433 
434     /* -------------------------------------------------------------------- *
435      * constructors.                                                        *
436      * -------------------------------------------------------------------- */
437 
438     public static CClass getCClass(String cName,
439 				   Package pkg,
440 				   CClass superClass,
441 				   Map<String, MapDecl> maps,
442 				   Map<String, CClassLink> subComponents,
443 				   Map<String, SClassDecl> effects
444 //,		  ClassLocator loc
445 	) {
446 	return new CClass(cName, pkg, superClass,
447 			  maps,
448 			  subComponents,
449 			  effects);
450     }
451 
452     public CClass(String cName,
453 		  Package pkg,
454 		  CClass superClass,
455 		  Map<String, MapDecl> maps,
456 		  Map<String, CClassLink> subComponents,
457 		  Map<String, SClassDecl> effects
458 //,		  ClassLocator loc
459 ) {
460 	this.cName = cName;
461 	this.pkg = pkg;
462 	this.superClass = superClass;
463 	this.maps = maps;
464 	this.subComponents = subComponents;
465 	this.effects = effects;
466 	
467 	//this.loc = loc;
468     } // CClass constructor
469 
470     /* -------------------------------------------------------------------- *
471      * methods.                                                             *
472      * -------------------------------------------------------------------- */
473 
474     /**
475      * Returns the short name of this class. 
476      *
477      * @return 
478      *    {@link #cName}. 
479      */
480     public final String getName() {
481 	return this.cName;
482     }
483 
484     /**
485      * Returns the package of this class. 
486      *
487      * @return 
488      *    {@link #pkg}. 
489      */
490     public final Package getPackage() {
491 	return this.pkg;
492     }
493 
494     /**
495      * Returns the superclass of this class. 
496      * This is <code>null</code> if and only if 
497      * this class is the unique overall base class {@link #COMPONENT}. 
498      *
499      * @return 
500      *    {@link #superClass}. 
501      */
502     public final CClass getSuperClass() {
503 	return this.superClass;
504     }
505 
506     /**
507      * Returns the map declaration with the given name. 
508      * The lookup is done recursively down the inheritance hierarchy. 
509      *
510      * @param name
511      *    the name of a declared map. 
512      * @return 
513      *    the map declaration with the given name 
514      *    or <code>null</code> if no declaration is defined with this name.  
515      */
516     @SuppressWarnings("checkstyle:designforextension")
517     // **** designforextension superfluous with checkstyle >=7.2 
518     public MapDecl getMapDecl(String name) {
519 	// Here, getSuperclass() returns non-null 
520 	MapDecl result = this.maps.get(name);
521 	if (result != null) {
522 	    return result;
523 	}
524 	return getSuperClass().getMapDecl(name);
525 
526     }
527 
528     /**
529      * Returns the map between names and subcomponent classes. 
530      *
531      * @return 
532      *    {@link #subComponents}. 
533      */
534     private Map<String, CClassLink> getName2ComponentClss() {
535 	return this.subComponents;
536     }
537 
538     @SuppressWarnings("checkstyle:designforextension")
539     // **** designforextension superfluous with checkstyle >=7.2 
540     public CClassLink getComponentCls(String name) {
541 	// Here, getSuperclass() returns non-null 
542 	CClassLink result = this.subComponents.get(name);
543 	if (result != null) {
544 	    return result;
545 	}
546 	return getSuperClass().getComponentCls(name);
547     }
548 
549     public final CClassLink getComponentCls(List<String> path) {
550 	CClass curr = this;
551 	for (String key : path) {
552 	    curr = (CClass) curr.getComponentCls(key);
553 	}
554 	
555 	return curr;
556     }
557 
558     @SuppressWarnings("checkstyle:designforextension")
559     // **** designforextension superfluous with checkstyle >=7.2 
560     Set<String> getComponentNames() {
561 	// Here, getSuperclass() returns non-null 
562 	Set<String> result = new TreeSet<String>
563 	    (getSuperClass().getComponentNames());
564 	result.addAll(getName2ComponentClss().keySet());
565 	return result;
566     }
567 
568     // **** as required in FormulaParser: 
569     // returns <code>null</code> if no effect with the given name is declared 
570     // lookup is recursively down the inheritance hierarchy. 
571     @SuppressWarnings("checkstyle:designforextension")
572     // **** designforextension superfluous with checkstyle >=7.2 
573     public SClassDecl getEffectDecl(String name) {
574 	// Here, getSuperclass() returns non-null 
575 	SClassDecl result = this.effects.get(name);
576 	if (result != null) {
577 	    return result;
578 	}
579 	
580 	return getSuperClass().getEffectDecl(name);
581     }
582 
583     // based on getEffectDecl(String)
584     public final SClassDecl getEffectDecl(List<String> path) {
585 	CClass curr = this;
586 	int ind = 0;
587 	for (; ind < path.size() - 1; ind++) {
588 	    curr = (CClass) curr.getComponentCls(path.get(ind));
589 	    // **** also in superclass?
590 	}
591 	
592 	return curr.getEffectDecl(path.get(ind));
593     }
594 
595     private Map<String, SClassDecl> getName2Effects() {
596 	return this.effects;
597     }
598 
599     // recursively down the inheritance hierarchy. 
600     @SuppressWarnings("checkstyle:designforextension")
601     // **** designforextension superfluous with checkstyle >=7.2 
602     Set<String> getEffectNames() {
603 	// Here, getSuperclass() returns non-null 
604 	Set<String> result = 
605 	    new TreeSet<String>(getSuperClass().getEffectNames());
606 	result.addAll(getName2Effects().keySet());
607 	return result;
608     }
609 
610 
611 
612     // **** should be recursive **** 
613     // **** needed in Relana only: check that enclosing instance has no input 
614     public final Set<SClassDecl> getEffectsRec() {
615 	Set<SClassDecl> res = new HashSet<SClassDecl>();
616 	// add immediate effects declarations 
617 	for (SClassDecl decl : this.effects.values()) {
618 	    res.add(decl);
619 	}
620 	/*
621 	for (Map.Entry<String, CClassLink> entry 
622 		 : this.subComponents.entrySet()) {
623 	    Map<ClassLocator, SClassDecl> resInner = 
624 		entry.getValue().getEffectsRec();
625 	    String prefix = entry.getKey();
626 	    Map<ClassLocator, SClassDecl> resInnerPre = 
627 		new HashMap<ClassLocator, SClassDecl>();
628 	    for (Map.Entry<ClassLocator, SClassDecl> ld : resInner.entrySet()) {
629 		List<String> l = new ArrayList<String>(ld.getKey().getPath());
630 		l.add(0, prefix);
631 
632 	    }
633 
634 	    res.put(ClassLocator.getLocator(entry.getKey()),
635 		    entry.getValue());
636 	}
637 	*/
638 	return res;
639     }
640 
641     // replacement of CClassLink by CClass. 
642     public final CClassLink setComponent(String name, CClass cClass) {
643 //System.out.println(": "+this.subComponents.put(name, cClass).getClass());
644 	return this.subComponents.put(name, cClass);
645     }
646 
647     @SuppressWarnings("checkstyle:designforextension")
648     // **** designforextension superfluous with checkstyle >=7.2 
649     void verify() throws VerifyException {
650 	// Here, getSuperclass() returns non-null 
651 	getSuperClass().verify();
652 
653 	// verify that a effect is declared only 
654 	// if not already declared in superclass 
655 	SClassDecl overwritten, overwrite;
656 	for (Map.Entry<String, SClassDecl> entry 
657 		 : getName2Effects().entrySet()) {
658 	    overwrite   = entry.getValue();
659 	    overwritten = getSuperClass().getEffectDecl(entry.getKey());
660 	    if (overwrite.isRedeclare()) {
661 		// is redeclare 
662 
663 		// check whether a declaration is overwritten 
664 		if (overwritten == null) {
665 		    // Here, a declaration is overwritten without redeclare 
666 		    throw new VerifyException
667 			("Found effect \"" + entry.getKey() + 
668 			 "\" redeclared in class \"" + getName() + 
669 			 "\" without being declared in any superclass. ");
670 		}
671 
672 		// check whether access modifiers fit 
673 		if ((overwritten.isOutput() && !overwrite.isOutput()) ||
674 		    (overwritten.isInput () && !overwrite.isInput ())) {
675 		    throw new VerifyException
676 			("Weakened access priviligies of effect \"" + 
677 			 entry.getKey() + 
678 			 "\" by redeclaration in class " + getName() + ". ");
679 		}
680 
681 
682 		// check whether overwrite  .getSClass() is a subclass 
683 		// of            overwritten.getSClass() 
684 		// and determine subclass map. 
685 
686 		SClass currentSCls = overwrite.getSClass();
687 		// compMap is a subclass map 
688 		//           currentSCls --> overwrite.getSClass()
689 		DeficiencyMap compMap = DeficiencyMap.identity(currentSCls);
690 		assert compMap.getTarget() == overwrite.getSClass();
691 		while (currentSCls != overwritten.getSClass()) {
692 		    assert compMap.getSource() == currentSCls;
693 		    if (currentSCls.getSuperClass() == null) {
694 			throw new VerifyException
695 			    ("Redeclared effect \"" + entry.getKey() + 
696 			     "\" of class " + 
697 			     overwritten.getSClass().getName() + 
698 			     " as " + overwrite.getSClass().getName() + 
699 			     " which is no subclass. ");
700 		    }
701 		    compMap = compMap.compose(currentSCls.getDeficiencyMap());
702 		    currentSCls = currentSCls.getSuperClass();		    
703 		}
704 		// Here, compMap is a subclass map 
705 		//    overwritten.getSClass()  --> overwrite.getSClass()
706 
707 		// **** here the maps between the variables could be installed 
708 		// but this would be bad design. 
709 	    } else {
710 		// is first declaration: no redeclare 
711 
712 		// nothing may be overwritten 
713 		if (overwritten != null) {
714 		    // Here, a declaration is overwritten without redeclare 
715 		    throw new VerifyException
716 			("Found effect \"" + entry.getKey() + 
717 			 "\" declared in class \"" + getName() + 
718 			 "\" and in a superclass: " + entry.getKey() + 
719 			 "; consider redeclare. ");
720 		}
721 	    }
722 	}
723 
724 	// verify that a component is declared only 
725 	// if not already declared in superclass 
726 	Set<String> names = 
727 	    new TreeSet<String>(getSuperClass().getComponentNames());
728 	names.retainAll(getName2ComponentClss().keySet());
729 	if (!names.isEmpty()) {
730 	    throw new VerifyException
731 		("Found components declared in class \"" + getName() + 
732 		    "\" and in a superclass: " + names + ". ");
733 	}
734     }
735 
736     /**
737      * Returns an instance of this class. 
738      * Also resolves formulae. 
739      *
740      * @return 
741      *    a <code>CInstance</code> of this class. 
742      */
743     @SuppressWarnings({
744 	    "PMD.SingletonClassReturningNewInstance", 
745 	    "PMD.SingleMethodSingleton", 
746 	    "checkstyle:designforextension"})
747 	    // **** designforextension superfluous with checkstyle >=7.2 
748     public CInstance getInstance() {
749 	// Here, getSuperclass() returns non-null 
750 	CInstance cInstance = getSuperClass().getInstance();
751 
752 	// instantiate and add subcomponents 
753 	CClass cClass;
754 	for (Map.Entry<String, CClassLink> cEntry 
755 		 : this.subComponents.entrySet()) {
756 	    cClass = (CClass) cEntry.getValue();
757 	    //cInstance = cClass.getInstance();
758 	    cInstance.addComponent(cEntry.getKey(),
759 				   cClass.getInstance());
760 	    //name2cInstance.put(cEntry.getKey(), cInstance);
761 	}
762 
763 	// instantiate and add effects 
764 	SInstance sInstance;
765 	SClassDecl decl;
766 	Map<SClassDecl, SInstance> declWithFormulae = 
767 	    new HashMap<SClassDecl, SInstance>();
768 	for (Map.Entry<String, SClassDecl> sEntry
769 		 : this.effects.entrySet()) {
770 	    decl = sEntry.getValue();
771 	    sInstance = decl.getSInstance();
772 
773 	    //name2sInstance.put(sEntry.getKey(), sInstance);
774 	    cInstance.addEffect(sEntry.getKey(), sInstance);
775 	    if (decl.getFormulaDecl() != null) {
776 		declWithFormulae.put(decl, sInstance);
777 	    }
778 	}
779 
780 	// resolve formulae 
781 	for (Map.Entry<SClassDecl, SInstance> entry 
782 		 : declWithFormulae.entrySet()) {
783 	    entry.getValue().setFormula(entry.getKey()
784 					.getFormulaDecl().resolve(cInstance));
785 	    //                           declaration      formula itself 
786 	}
787 	
788 	return cInstance;
789     }
790 
791     public void addOccurrence(CClassLoader.Occurrence occ) {
792 	    // is empty. 
793     }
794 
795     public final boolean isResolved() {
796 	return true;
797     }
798 
799     public final String toString() {
800 	StringBuffer res = new StringBuffer();
801 
802 	res.append("\n<CClass name=\"");
803 	res.append(this.cName);
804 	res.append("\" package=\"");
805 	res.append(this.pkg);
806 	res.append("\" superClass=\"");
807 	res.append(this.superClass.getName());
808 	res.append("\">\n");
809 	for (Map.Entry<String, MapDecl> entry 
810 		 : this.maps.entrySet()) {
811 	    res.append("<map name=\"");
812 	    res.append(entry.getKey());
813 	    res.append("\"/>\n");
814 	    res.append(entry.getValue());
815 	    res.append("</map>");
816 	}
817 	for (Map.Entry<String, CClassLink> entry 
818 		 : this.subComponents.entrySet()) {
819 	    res.append("<component name=\"");
820 	    res.append(entry.getKey());
821 	    res.append("\" class=\"");
822 	    res.append(entry.getValue().getName());
823 	    res.append("\"/>\n");
824 	}
825 
826 	res.append("\n<effects>");
827 	for (SClassDecl decl : this.effects.values()) {
828 	    res.append(decl.toString());
829 	}
830 	res.append("\n</effects>\n</CClass>\n");
831 	return res.toString();
832     }
833 
834 } // CClass