View Javadoc

1   /***
2    * 
3    */
4   package org.xvsm.internal;
5   
6   import java.net.URI;
7   import java.util.ArrayList;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.StringTokenizer;
11  import java.util.UUID;
12  import java.util.concurrent.ConcurrentHashMap;
13  
14  import org.xvsm.core.aspect.AspectContext;
15  import org.xvsm.core.aspect.GlobalIPoint;
16  import org.xvsm.core.aspect.IAspect;
17  import org.xvsm.core.aspect.IPoint;
18  import org.xvsm.core.aspect.LocalIPoint;
19  import org.xvsm.internal.exceptions.AspectNotOkException;
20  import org.xvsm.internal.exceptions.AspectRescheduleException;
21  import org.xvsm.internal.exceptions.AspectSkipException;
22  
23  /***
24   * @author Christian Schreiber, Michael Proestler
25   * 
26   */
27  public class AspectManager {
28  
29  	/***
30  	 * Map contains all registered aspects.
31  	 */
32  	private Map<IPoint, List<IAspect>> aspects = new ConcurrentHashMap<IPoint, List<IAspect>>();
33  
34  	private Map<String, IAspect> idaspectMapping = new ConcurrentHashMap<String, IAspect>();
35  
36  	/***
37  	 * Default constructor.
38  	 */
39  	public AspectManager() {
40  		for (LocalIPoint p : LocalIPoint.values()) {
41  			aspects.put(p, new ArrayList<IAspect>());
42  		}
43  		for (GlobalIPoint p : GlobalIPoint.values()) {
44  			aspects.put(p, new ArrayList<IAspect>());
45  		}
46  	}
47  
48  	/***
49  	 * Adds a new Aspect.
50  	 * 
51  	 * @param p
52  	 *            the ipoint for the new aspect.
53  	 * @param aspect
54  	 *            the new aspect.
55  	 * @return the identifier of the aspect
56  	 */
57  	public String addAspect(IPoint p, IAspect aspect) {
58  		if (aspect.getId() == null) {
59  			aspect.setId(UUID.randomUUID().toString());
60  		}
61  		this.aspects.get(p).add(aspect);
62  		this.idaspectMapping.put(aspect.getId(), aspect);
63  		return aspect.getId();
64  	}
65  
66  	/***
67  	 * Removes an aspect.
68  	 * 
69  	 * @param p
70  	 *            the ipoint where the aspect shall be removed.
71  	 * @param uri
72  	 *            the uri of the aspect which shall be removed.
73  	 */
74  	public void removeAspect(IPoint p, URI uri) {
75  		StringTokenizer st = new StringTokenizer(uri.getPath(), "/");
76  		st.nextToken(); // ignore == aspects
77  		String id = st.nextToken();
78  		this.aspects.get(p).remove(this.idaspectMapping.get(id));
79  		for (IPoint pp : this.aspects.keySet()) {
80  			// check if the aspect is used at another ipoint.
81  			if (this.aspects.containsKey(pp)) {
82  				return;
83  			}
84  			// remove the aspect from the idaspectmapping
85  			this.idaspectMapping.remove(id);
86  			System.gc();
87  		}
88  	}
89  
90  	/***
91  	 * Returns all registered aspects for the IPoint.
92  	 * 
93  	 * @param p
94  	 *            the IPoint.
95  	 * @return a list of aspects.
96  	 */
97  	private List<IAspect> getAspects(IPoint p) {
98  		return this.aspects.get(p);
99  	}
100 
101 	/***
102 	 * Runs all aspects which have been registered for the IPoint defined in c.
103 	 * 
104 	 * @param c
105 	 *            the {@link AspectContext}.
106 	 * @throws AspectNotOkException
107 	 *             thrown if the operation has to be rescheduled.
108 	 * @throws AspectRescheduleException
109 	 *             thrown if the operation has to be undone and the transaction
110 	 *             has to be rolled back.
111 	 * @throws AspectSkipException
112 	 *             thrown if the operation shall be skiped.
113 	 */
114 	public void execute(AspectContext c) throws AspectNotOkException,
115 			AspectRescheduleException, AspectSkipException {
116 
117 		List<IAspect> allAspects = new ArrayList<IAspect>();
118 		IPoint p = c.getLocalIPoint();
119 		if (p != null) {
120 			allAspects.addAll(this.getAspects(p));
121 		}
122 		p = c.getGlobalIPoint();
123 		if (p != null) {
124 			allAspects.addAll(this.getAspects(p));
125 		}
126 		for (IAspect a : allAspects) {
127 			// execute the aspects
128 			a.execute(c);
129 		}
130 
131 	}
132 }