001: package net.refractions.udig.project.internal.impl;
002:
003: import java.io.IOException;
004: import java.io.StringReader;
005: import java.io.StringWriter;
006: import java.net.URL;
007: import java.util.Arrays;
008: import java.util.Collection;
009: import java.util.HashMap;
010: import java.util.Iterator;
011: import java.util.List;
012: import java.util.concurrent.CopyOnWriteArraySet;
013: import java.util.concurrent.locks.Lock;
014:
015: import net.refractions.udig.core.internal.ExtensionPointProcessor;
016: import net.refractions.udig.core.internal.ExtensionPointUtil;
017: import net.refractions.udig.project.BlackboardEvent;
018: import net.refractions.udig.project.IBlackboardListener;
019: import net.refractions.udig.project.StyleContent;
020: import net.refractions.udig.project.internal.ProjectFactory;
021: import net.refractions.udig.project.internal.ProjectPackage;
022: import net.refractions.udig.project.internal.ProjectPlugin;
023: import net.refractions.udig.project.internal.StyleBlackboard;
024: import net.refractions.udig.project.internal.StyleEntry;
025: import net.refractions.udig.ui.UDIGDisplaySafeLock;
026: import net.refractions.udig.ui.graphics.SLDs;
027:
028: import org.eclipse.core.runtime.IConfigurationElement;
029: import org.eclipse.core.runtime.IExtension;
030: import org.eclipse.core.runtime.IProgressMonitor;
031: import org.eclipse.emf.common.notify.NotificationChain;
032: import org.eclipse.emf.common.util.EList;
033: import org.eclipse.emf.ecore.EClass;
034: import org.eclipse.emf.ecore.EStructuralFeature;
035: import org.eclipse.emf.ecore.InternalEObject;
036: import org.eclipse.emf.ecore.impl.EObjectImpl;
037: import org.eclipse.emf.ecore.util.EObjectContainmentEList;
038: import org.eclipse.emf.ecore.util.InternalEList;
039: import org.eclipse.ui.WorkbenchException;
040: import org.eclipse.ui.XMLMemento;
041: import org.geotools.styling.Style;
042: import org.geotools.styling.StyledLayerDescriptor;
043: import org.geotools.styling.StyledLayerDescriptorImpl;
044: import org.geotools.styling.UserLayer;
045: import org.geotools.styling.UserLayerImpl;
046:
047: /**
048: * The default implementation.
049: *
050: * @author Jesse
051: * @since 1.0.0
052: * @generated
053: */
054: public class StyleBlackboardImpl extends EObjectImpl implements
055: StyleBlackboard {
056: /**
057: * <!-- begin-user-doc --> <!-- end-user-doc -->
058: * @generated
059: */
060: public static final String copyright = "uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004, Refractions Research Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details."; //$NON-NLS-1$
061:
062: /**
063: * The cached value of the '{@link #getContent() <em>Content</em>}' containment reference list.
064: * <!-- begin-user-doc --> <!-- end-user-doc -->
065: * @see #getContent()
066: * @generated
067: * @ordered
068: */
069: protected EList content = null;
070:
071: Lock contentLock = new UDIGDisplaySafeLock();
072:
073: /**
074: * Map of style id to StyleContent
075: *
076: * @uml.property name="id2content"
077: * @uml.associationEnd qualifier="key:java.lang.Object
078: * net.refractions.udig.project.StyleContent"
079: * @generated NOT
080: */
081: protected HashMap<String, StyleContent> id2content = new HashMap<String, StyleContent>();
082:
083: /**
084: * <!-- begin-user-doc --> <!-- end-user-doc -->
085: * @generated
086: */
087: protected StyleBlackboardImpl() {
088: super ();
089: }
090:
091: /**
092: * <!-- begin-user-doc --> <!-- end-user-doc -->
093: * @generated
094: */
095: protected EClass eStaticClass() {
096: return ProjectPackage.eINSTANCE.getStyleBlackboard();
097: }
098:
099: /**
100: * <!-- begin-user-doc --> <!-- end-user-doc -->
101: * @generated
102: */
103: @SuppressWarnings("unchecked")
104: public List<StyleEntry> getContent() {
105: if (content == null) {
106: content = new EObjectContainmentEList(StyleEntry.class,
107: this , ProjectPackage.STYLE_BLACKBOARD__CONTENT) {
108:
109: /** long serialVersionUID field */
110: private static final long serialVersionUID = 1L;
111:
112: @Override
113: protected Object assign(int index, Object object) {
114: contentLock.lock();
115: try {
116: return super .assign(index, object);
117: } finally {
118: contentLock.unlock();
119: }
120: }
121:
122: @Override
123: protected void doClear() {
124: contentLock.lock();
125: try {
126: super .doClear();
127: } finally {
128: contentLock.unlock();
129: }
130: }
131:
132: @Override
133: protected Object doRemove(int index) {
134: contentLock.lock();
135: try {
136: return super .doRemove(index);
137: } finally {
138: contentLock.unlock();
139: }
140: }
141:
142: };
143: }
144: return content;
145: }
146:
147: /**
148: * <!-- begin-user-doc --> <!-- end-user-doc -->
149: *
150: * @generated NOT
151: */
152: public Object get(String styleId) {
153: StyleEntry entry = getEntry(styleId);
154: if (entry == null)
155: return null;
156: return getObject(entry);
157: }
158:
159: private StyleEntry getEntry(String styleId) {
160: StyleEntry entry = null;
161: contentLock.lock();
162: try {
163: for (Iterator seItr = getContent().iterator(); seItr
164: .hasNext();) {
165: StyleEntry se = (StyleEntry) seItr.next();
166: if (se.getID().equals(styleId)) {
167: entry = se;
168: break;
169: }
170: }
171: } finally {
172: contentLock.unlock();
173: }
174: return entry;
175: }
176:
177: /**
178: * <!-- begin-user-doc --> <!-- end-user-doc -->
179: *
180: * @generated NOT
181: */
182: public Object lookup(Class<?> theClass) {
183: StyleEntry entry = null;
184: contentLock.lock();
185: try {
186: for (Iterator seItr = getContent().iterator(); seItr
187: .hasNext();) {
188: StyleEntry se = (StyleEntry) seItr.next();
189: if (se.getStyleClass() == null) {
190: StyleContent styleContent = getStyleContent(se
191: .getID());
192: if (styleContent != null)
193: se.setStyleClass(styleContent.getStyleClass());
194: else {
195: continue;
196: }
197: }
198: if (theClass.isAssignableFrom(se.getStyleClass())) {
199: entry = se;
200: break;
201: }
202: }
203: } finally {
204: contentLock.unlock();
205: }
206:
207: if (entry == null)
208: return null;
209: return getObject(entry);
210: }
211:
212: /**
213: * Gets the style object from a StyleEntry. Either from the StyleEntry cache or from the
214: * StyleContent associated with the entry.
215: *
216: * @generated NOT
217: */
218: protected Object getObject(StyleEntry styleEntry) {
219: // reload style state if necessary
220: if (styleEntry.getStyle() == null) {
221: try {
222: StyleContent styleContent = getStyleContent(styleEntry
223: .getID());
224: XMLMemento memento = XMLMemento
225: .createReadRoot(new StringReader(styleEntry
226: .getMemento()));
227: Object style = styleContent.load(memento);
228: styleEntry.setStyle(style);
229: } catch (WorkbenchException e) {
230: e.printStackTrace();
231: }
232: }
233:
234: return styleEntry.getStyle();
235: }
236:
237: /**
238: * <!-- begin-user-doc --> <!-- end-user-doc -->
239: *
240: * @generated NOT
241: */
242: public boolean contains(String styleId) {
243: return get(styleId) != null;
244: }
245:
246: /**
247: * <!-- begin-user-doc --> <!-- end-user-doc -->
248: *
249: * @generated NOT
250: */
251: @SuppressWarnings("unchecked")
252: public void put(String styleId, Object style) {
253: remove(styleId);
254:
255: //Validate (add an SLD to the style if one does not exist)
256: //TODO: move to extension point
257: if (style instanceof Style) {
258: Style theStyle = (Style) style;
259: Object SLD = SLDs.styledLayerDescriptor(theStyle);
260: if (SLD == null) {
261: StyledLayerDescriptor sld = new StyledLayerDescriptorImpl();
262: UserLayer layer = new UserLayerImpl();
263: layer.getNote().setParent(sld);
264: theStyle.getNote().setParent(layer);
265: }
266: }
267:
268: StyleEntry se = ProjectFactory.eINSTANCE.createStyleEntry();
269:
270: Object oldValue = se.getStyle();
271:
272: se.setID(styleId);
273: se.setStyle(style);
274:
275: content.add(se);
276:
277: StyleContent styleContent = getStyleContent(styleId);
278:
279: if (styleContent == null)
280: return;
281: try {
282: // save the state of the style
283: XMLMemento memento = XMLMemento
284: .createWriteRoot("styleEntry"); //$NON-NLS-1$
285: styleContent.save(memento, style);
286:
287: StringWriter writer = new StringWriter();
288: memento.save(writer);
289: se.setMemento(writer.getBuffer().toString());
290:
291: writer.close();
292: } catch (IOException e) {
293: e.printStackTrace();
294: }
295:
296: BlackboardEvent event = new BlackboardEvent(this , styleId,
297: oldValue, style);
298: for (IBlackboardListener l : listeners) {
299: try {
300: l.blackBoardChanged(event);
301: } catch (Exception e) {
302: ProjectPlugin.log("", e); //$NON-NLS-1$
303: }
304: }
305:
306: }
307:
308: /**
309: * <!-- begin-user-doc --> <!-- end-user-doc -->
310: *
311: * @generated NOT
312: */
313: public void put(URL url, IProgressMonitor monitor) {
314: createStyleEntry(url, monitor);
315: }
316:
317: /**
318: * @generated NOT
319: */
320: private StyleContent getStyleContent(String styleId) {
321:
322: // look in local cache first
323: StyleContent styleContent = id2content.get(styleId);
324: if (styleContent == null) {
325: loadStyleContent(styleId);
326: styleContent = id2content.get(styleId);
327: }
328: return styleContent;
329: }
330:
331: /**
332: * @generated NOT
333: */
334: private void loadStyleContent(final String styleId) {
335:
336: ExtensionPointProcessor p = new ExtensionPointProcessor() {
337: boolean found = false;
338:
339: public void process(IExtension extension,
340: IConfigurationElement element) throws Exception {
341: if (!found
342: && element.getAttribute("id").equals(styleId)) { //$NON-NLS-1$
343: found = true;
344: id2content.put(styleId, (StyleContent) element
345: .createExecutableExtension("class") //$NON-NLS-1$
346: );
347: }
348: }
349: };
350: ExtensionPointUtil.process(ProjectPlugin.getPlugin(),
351: StyleContent.XPID, p);
352:
353: }
354:
355: class URLProcessor implements ExtensionPointProcessor {
356: boolean found = false;
357:
358: Object style = null;
359:
360: String id;
361:
362: URL url;
363:
364: IProgressMonitor monitor;
365:
366: public URLProcessor(URL url, IProgressMonitor monitor) {
367: this .url = url;
368: this .monitor = monitor;
369: }
370:
371: /*
372: * @see net.refractions.udig.core.internal.ExtensionPointProcessor#process(org.eclipse.core.runtime.IExtension,
373: * org.eclipse.core.runtime.IConfigurationElement)
374: */
375: public void process(IExtension extension,
376: IConfigurationElement element) throws Exception {
377: if (found)
378: return;
379:
380: StyleContent styleContent = (StyleContent) element
381: .createExecutableExtension("class"); //$NON-NLS-1$
382: style = styleContent.load(url, monitor);
383: if (style != null) {
384: id = styleContent.getId();
385: id2content.put(styleContent.getId(), styleContent);
386: found = true;
387: }
388: }
389: }
390:
391: /**
392: * @generated NOT
393: */
394: private Object createStyleEntry(URL url, IProgressMonitor monitor) {
395: URLProcessor p = new URLProcessor(url, monitor);
396: ExtensionPointUtil.process(ProjectPlugin.getPlugin(),
397: StyleContent.XPID, p);
398:
399: if (p.style != null) {
400: put(p.id, p.style);
401: }
402:
403: return p.style;
404: }
405:
406: /**
407: * <!-- begin-user-doc --> <!-- end-user-doc -->
408: *
409: * @generated NOT
410: */
411: public Object remove(String styleId) {
412: Object style = null;
413: contentLock.lock();
414: try {
415: for (Iterator seItr = getContent().iterator(); seItr
416: .hasNext();) {
417: StyleEntry se = (StyleEntry) seItr.next();
418: if (se.getID().equals(styleId)) {
419: style = se.getStyle();
420: seItr.remove();
421: }
422: }
423: } finally {
424: contentLock.unlock();
425: }
426:
427: return style;
428: }
429:
430: /**
431: * <!-- begin-user-doc --> TODO: This method does not actually clone the underlying style
432: * objects, which it should. <!-- end-user-doc -->
433: * @throws CloneNotSupportedException
434: *
435: * @generated NOT
436: */
437: public Object clone() {
438: // clone the entire blackboard
439: StyleBlackboardImpl clone;
440: try {
441: clone = (StyleBlackboardImpl) super .clone();
442: } catch (CloneNotSupportedException e) {
443: clone = (StyleBlackboardImpl) ProjectFactory.eINSTANCE
444: .createStyleBlackboard();
445: }
446:
447: clone.content = null;
448:
449: contentLock.lock();
450: try {
451: for (Iterator seItr = getContent().iterator(); seItr
452: .hasNext();) {
453: StyleEntry styleEntry = (StyleEntry) seItr.next();
454:
455: StyleEntry styleEntryClone = ProjectFactory.eINSTANCE
456: .createStyleEntry();
457:
458: // clone the entry by copying the id + memento over
459: styleEntryClone.setID(styleEntry.getID());
460: styleEntryClone.setMemento(styleEntry.getMemento());
461: clone.getContent().add(styleEntryClone);
462: }
463: } finally {
464: contentLock.unlock();
465: }
466: return clone;
467: }
468:
469: /**
470: * <!-- begin-user-doc --> <!-- end-user-doc -->
471: * @generated
472: */
473: @SuppressWarnings("unchecked")
474: public NotificationChain eInverseRemove(InternalEObject otherEnd,
475: int featureID, Class baseClass, NotificationChain msgs) {
476: if (featureID >= 0) {
477: switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
478: case ProjectPackage.STYLE_BLACKBOARD__CONTENT:
479: return ((InternalEList) getContent()).basicRemove(
480: otherEnd, msgs);
481: default:
482: return eDynamicInverseRemove(otherEnd, featureID,
483: baseClass, msgs);
484: }
485: }
486: return eBasicSetContainer(null, featureID, msgs);
487: }
488:
489: /**
490: * <!-- begin-user-doc --> <!-- end-user-doc -->
491: * @generated
492: */
493: public Object eGet(EStructuralFeature eFeature, boolean resolve) {
494: switch (eDerivedStructuralFeatureID(eFeature)) {
495: case ProjectPackage.STYLE_BLACKBOARD__CONTENT:
496: return getContent();
497: }
498: return eDynamicGet(eFeature, resolve);
499: }
500:
501: /**
502: * <!-- begin-user-doc --> <!-- end-user-doc -->
503: * @generated
504: */
505: @SuppressWarnings("unchecked")
506: public void eSet(EStructuralFeature eFeature, Object newValue) {
507: switch (eDerivedStructuralFeatureID(eFeature)) {
508: case ProjectPackage.STYLE_BLACKBOARD__CONTENT:
509: getContent().clear();
510: getContent().addAll((Collection) newValue);
511: return;
512: }
513: eDynamicSet(eFeature, newValue);
514: }
515:
516: /**
517: * <!-- begin-user-doc --> <!-- end-user-doc -->
518: * @generated
519: */
520: public void eUnset(EStructuralFeature eFeature) {
521: switch (eDerivedStructuralFeatureID(eFeature)) {
522: case ProjectPackage.STYLE_BLACKBOARD__CONTENT:
523: getContent().clear();
524: return;
525: }
526: eDynamicUnset(eFeature);
527: }
528:
529: /**
530: * <!-- begin-user-doc --> <!-- end-user-doc -->
531: * @generated
532: */
533: public boolean eIsSet(EStructuralFeature eFeature) {
534: switch (eDerivedStructuralFeatureID(eFeature)) {
535: case ProjectPackage.STYLE_BLACKBOARD__CONTENT:
536: return content != null && !content.isEmpty();
537: }
538: return eDynamicIsSet(eFeature);
539: }
540:
541: /**
542: * @see net.refractions.udig.project.IBlackboard#getFloat(java.lang.String)
543: */
544: public Float getFloat(String key) {
545: if (contains(key)) {
546: Object value = get(key);
547: if (value instanceof Float) {
548: return (Float) value;
549: }
550: }
551: return null;
552: }
553:
554: public Integer getInteger(String key) {
555: if (contains(key)) {
556: Object value = get(key);
557: if (value instanceof Integer) {
558: return (Integer) value;
559: }
560: }
561: return null;
562: }
563:
564: public String getString(String key) {
565: if (contains(key)) {
566: Object value = get(key);
567: if (value instanceof String) {
568: return (String) value;
569: }
570: }
571: return null;
572: }
573:
574: public void putFloat(String key, float value) {
575: put(key, value);
576: }
577:
578: public void putInteger(String key, int value) {
579: put(key, value);
580: }
581:
582: public void putString(String key, String value) {
583: put(key, value);
584: }
585:
586: public void clear() {
587: if (content == null)
588: return;
589: content.clear();
590:
591: for (IBlackboardListener l : listeners) {
592: try {
593: l.blackBoardCleared(this );
594: } catch (Exception e) {
595: ProjectPlugin.log("", e); //$NON-NLS-1$
596: }
597: }
598: }
599:
600: public void flush() {
601:
602: }
603:
604: CopyOnWriteArraySet<IBlackboardListener> listeners = new CopyOnWriteArraySet<IBlackboardListener>();
605:
606: public boolean addListener(IBlackboardListener listener) {
607: return listeners.add(listener);
608: }
609:
610: public boolean removeListener(IBlackboardListener listener) {
611: return listeners.remove(listener);
612: }
613:
614: public void setSelected(String[] ids) {
615: List<String> idList = Arrays.asList(ids);
616: contentLock.lock();
617: try {
618: List<StyleEntry> entries = getContent();
619: for (StyleEntry entry : entries) {
620: if (idList.contains(entry.getID()))
621: entry.setSelected(true);
622: else
623: entry.setSelected(false);
624: }
625: } finally {
626: contentLock.unlock();
627: }
628:
629: }
630:
631: public boolean isSelected(String styleId) {
632: StyleEntry entry = getEntry(styleId);
633:
634: if (entry != null && entry.isSelected())
635: return true;
636: return false;
637: }
638:
639: } // StyleBlackboardImpl
|