001: /**
002: * <copyright></copyright> $Id$
003: */package net.refractions.udig.project.internal.render.impl;
004:
005: import java.util.ArrayList;
006: import java.util.Collection;
007: import java.util.Collections;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Set;
011: import java.util.TreeSet;
012: import java.util.concurrent.CopyOnWriteArraySet;
013:
014: import net.refractions.udig.project.internal.Layer;
015: import net.refractions.udig.project.internal.render.CompositeRenderContext;
016: import net.refractions.udig.project.internal.render.RenderContext;
017: import net.refractions.udig.project.render.ICompositeRenderContext;
018: import net.refractions.udig.project.render.IRenderContext;
019:
020: /**
021: * Default Implementation
022: *
023: * @author Jesse
024: * @since 1.0.0
025: * @generated
026: */
027: public class CompositeRenderContextImpl extends RenderContextImpl
028: implements CompositeRenderContext {
029: /**
030: * The cached value of the '{@link #getContextsInternal() <em>Contexts Internal</em>}'
031: * reference list.
032: *
033: * @see #getContextsInternal()
034: */
035: protected final Collection<RenderContext> contextsInternal = Collections
036: .synchronizedSortedSet(new TreeSet<RenderContext>());
037: private final Set<CompositeContextListener> listeners = new CopyOnWriteArraySet<CompositeContextListener>();
038:
039: public CompositeRenderContextImpl() {
040: super ();
041: }
042:
043: public CompositeRenderContextImpl(CompositeRenderContextImpl impl) {
044: super (impl);
045: assert assertNoSelfReference(this , this , impl.contextsInternal);
046: synchronized (impl.contextsInternal) {
047: for (RenderContext context : impl.contextsInternal) {
048: if (context == impl) {
049: contextsInternal.add(this );
050: } else
051: contextsInternal.add(context.copy());
052: }
053: }
054: }
055:
056: public boolean isVisible() {
057: if (getLayer() != null && getLayer().isVisible())
058: return true;
059: for (Iterator iter = getContexts().iterator(); iter.hasNext();) {
060: IRenderContext context = (IRenderContext) iter.next();
061: if (context == this )
062: continue;
063: if (context.isVisible())
064: return true;
065: }
066: return false;
067: }
068:
069: public List<Layer> getLayersInternal() {
070: List<Layer> list = new ArrayList<Layer>();
071: synchronized (contextsInternal) {
072: for (RenderContext context : contextsInternal)
073: list.add(context.getLayerInternal());
074: }
075: return Collections.unmodifiableList(list);
076: }
077:
078: @SuppressWarnings("unchecked")
079: public List getLayers() {
080: return getLayersInternal();
081: }
082:
083: @SuppressWarnings("unchecked")
084: public List getContexts() {
085: synchronized (contextsInternal) {
086: return Collections.unmodifiableList(new ArrayList<Object>(
087: contextsInternal));
088: }
089: }
090:
091: @Override
092: public String toString() {
093: if (contextsInternal.isEmpty()) {
094: return super .toString();
095: }
096:
097: StringBuffer buffer = new StringBuffer("{CompositeContext: "); //$NON-NLS-1$
098: synchronized (contextsInternal) {
099:
100: for (RenderContext context : contextsInternal) {
101: if (context == this )
102: buffer.append("\n -" + super .toString()); //$NON-NLS-1$
103: else
104: buffer.append("\n -" + context.toString()); //$NON-NLS-1$
105: }
106: buffer.append("\n}"); //$NON-NLS-1$
107: return buffer.length() == 0 ? super .toString() : buffer
108: .toString();
109: }
110: }
111:
112: @Override
113: public void setStatus(int status) {
114: if (getContexts().size() == 0) {
115: super .setStatus(status);
116: return;
117: }
118:
119: synchronized (contextsInternal) {
120:
121: for (RenderContext context : contextsInternal) {
122: if (context != this )
123: context.setStatus(status);
124: else
125: super .setStatus(status);
126: }
127: }
128: }
129:
130: @Override
131: public void setStatusMessage(String message) {
132: if (getContexts().size() == 0) {
133: super .setStatusMessage(message);
134: return;
135: }
136: synchronized (contextsInternal) {
137: for (RenderContext context : contextsInternal) {
138: if (context != this )
139: context.setStatusMessage(message);
140: else
141: super .setStatusMessage(message);
142: }
143: }
144:
145: }
146:
147: @Override
148: public void dispose() {
149: super .dispose();
150: synchronized (contextsInternal) {
151: for (RenderContext context : contextsInternal) {
152: if (context != this )
153: ((RenderContextImpl) context).dispose();
154: }
155: }
156: }
157:
158: public void addListener(CompositeContextListener contextListener) {
159: listeners.add(contextListener);
160: }
161:
162: public void removeListener(CompositeContextListener contextListener) {
163: listeners.remove(contextListener);
164: }
165:
166: private void notifyListeners(List<RenderContext> contexts,
167: boolean added) {
168: for (CompositeContextListener l : listeners) {
169: l.notifyChanged(this , contexts, added);
170: }
171: }
172:
173: public void clear() {
174: List<RenderContext> contexts;
175: synchronized (contextsInternal) {
176: contexts = new ArrayList<RenderContext>(contextsInternal);
177: }
178: contextsInternal.clear();
179: if (!contexts.isEmpty())
180: notifyListeners(contexts, false);
181: }
182:
183: public void addContexts(Collection<? extends RenderContext> contexts) {
184: if (contexts.isEmpty())
185: return;
186: assert assertNoSelfReference(this , this , contexts);
187: contextsInternal.addAll(contexts);
188: notifyListeners(new ArrayList<RenderContext>(contexts), true);
189: }
190:
191: /**
192: * For testing and assertions that the context is in good state.
193: *
194: * @return
195: */
196: public static boolean assertNoSelfReference(IRenderContext parent,
197: IRenderContext reference,
198: Collection<? extends IRenderContext> contexts) {
199: for (IRenderContext context : contexts) {
200:
201: if (context == parent)
202: continue;
203:
204: if (context == reference)
205: return false;
206:
207: if (context instanceof ICompositeRenderContext) {
208: ICompositeRenderContext comp = (ICompositeRenderContext) context;
209: List<IRenderContext> children = comp.getContexts();
210: for (IRenderContext context2 : children) {
211: if (context2 == null)
212: return false;
213:
214: if (context2 instanceof ICompositeRenderContext) {
215: if (!assertNoSelfReference(context2, reference,
216: ((ICompositeRenderContext) context2)
217: .getContexts()))
218: return false;
219: }
220: }
221: }
222: }
223: return true;
224: }
225:
226: public void removeContexts(
227: Collection<? extends RenderContext> contexts) {
228: if (contexts.isEmpty())
229: return;
230: contextsInternal.removeAll(contexts);
231: notifyListeners(new ArrayList<RenderContext>(contexts), false);
232: }
233:
234: @Override
235: public CompositeRenderContextImpl copy() {
236: return new CompositeRenderContextImpl(this );
237: }
238:
239: @Override
240: public int hashCode() {
241: final int PRIME = 31;
242: int result = super .hashCode();
243:
244: for (RenderContext context : contextsInternal) {
245: if (context == this )
246: result = PRIME * result + super .hashCode();
247: else
248: result = PRIME * result + context.hashCode();
249: }
250: return result;
251: }
252:
253: @Override
254: public boolean equals(Object obj) {
255: if (!(obj instanceof CompositeRenderContextImpl))
256: return false;
257: if (this == obj)
258: return true;
259: if (!super .equals(obj))
260: return false;
261: if (getClass() != obj.getClass())
262: return false;
263: final CompositeRenderContextImpl other = (CompositeRenderContextImpl) obj;
264: if (contextsInternal == null) {
265: if (other.contextsInternal != null)
266: return false;
267: } else if (!contextsEqual(other))
268: return false;
269: return true;
270: }
271:
272: @Override
273: public int compareTo(RenderContext o) {
274: if (o == this )
275: return 0;
276: int result = super .compareTo(o);
277: // check the order of children also. If they are not the same the return -1.
278: // this is done so that TreeMap and TreeSet will not think 2 contexts are the same if they
279: // have the same layer. identity also takes the child contexts into account.
280: if (result == 0) {
281: if (o instanceof ICompositeRenderContext) {
282: ICompositeRenderContext comp = (ICompositeRenderContext) o;
283: if (contextsEqual(comp))
284: return 0;
285: else
286: return -1;
287: } else {
288: return -1;
289: }
290: }
291: return result;
292: }
293:
294: @SuppressWarnings("unchecked")
295: private boolean contextsEqual(ICompositeRenderContext o) {
296: if (o.getContexts().size() != contextsInternal.size())
297: return false;
298:
299: Iterator<IRenderContext> iter1 = getContexts().iterator();
300: Iterator<IRenderContext> iter2 = o.getContexts().iterator();
301: while (iter1.hasNext()) {
302: IRenderContext o1 = iter1.next();
303: IRenderContext o2 = iter2.next();
304:
305: if (o1 == this ) {
306: if (o2 == o)
307: continue;
308: else
309: return false;
310: }
311: if (!o1.equals(o2))
312: return false;
313: }
314: return true;
315: }
316:
317: } // CompositeRenderContextImpl
|