001: package net.refractions.udig.project.ui;
002:
003: import java.util.ArrayList;
004: import java.util.Collections;
005: import java.util.HashMap;
006: import java.util.Iterator;
007: import java.util.List;
008: import java.util.Map.Entry;
009: import java.util.logging.Level;
010: import java.util.logging.Logger;
011:
012: import net.refractions.udig.project.geoselection.AbstractGeoSelectionManager;
013: import net.refractions.udig.project.geoselection.GeoSelectionChangedEvent;
014: import net.refractions.udig.project.geoselection.GeoSelectionEntry;
015: import net.refractions.udig.project.geoselection.IGeoSelection;
016: import net.refractions.udig.project.geoselection.IGeoSelectionChangedListener;
017: import net.refractions.udig.project.geoselection.IGeoSelectionEntry;
018: import net.refractions.udig.project.internal.Map;
019: import net.refractions.udig.project.ui.internal.ApplicationGISInternal;
020: import net.refractions.udig.project.ui.internal.MapEditor;
021:
022: import org.eclipse.ui.IEditorPart;
023: import org.eclipse.ui.IPartListener2;
024: import org.eclipse.ui.IWorkbenchPage;
025: import org.eclipse.ui.IWorkbenchPartReference;
026: import org.eclipse.ui.IWorkbenchWindow;
027: import org.eclipse.ui.PlatformUI;
028:
029: /**
030: *
031: * The UDIG platform standard geoselection manager instance.
032: * <p>
033: * It is returned by GeoSelectionService.getPlatformSelectionManager().
034: *
035: * @author Vitalus
036: * @since UDIG 1.1
037: */
038: public class PlatformGeoSelectionManager extends
039: AbstractGeoSelectionManager {
040:
041: /**
042: * ID of the manager.
043: */
044: public static final String ID = "net.refractions.udig.project.ui.platformGeoSelectionManager"; //$NON-NLS-1$
045:
046: /**
047: * Logger.
048: */
049: public static Logger LOGGER = Logger
050: .getLogger("net.refractions.udig.project.geoselection"); //$NON-NLS-1$
051:
052: /**
053: * Key for selection bag in Map's blackboard.
054: */
055: public static final String PLATFORM_SELECTION_BAG = "net.refractions.udig.project.ui.PLATFORM_SELECTION_BAG"; //$NON-NLS-1$
056:
057: /**
058: * Key for cached selection bag in Map's blackboard.
059: */
060: public static final String PLATFORM_SELECTION_CACHE_KEY = "net.refractions.udig.project.ui.PLATFORM_SELECTION_CACHE"; //$NON-NLS-1$
061:
062: private MapEditorPartListener partListener;
063:
064: private List<IGeoSelectionEntry> cachedSelections;
065:
066: private IGeoSelectionEntry latestGeoSelection = null;
067:
068: private boolean initialized = false;
069:
070: /**
071: * Current active Map.
072: */
073: protected Map currentMap;
074:
075: /**
076: *
077: */
078: public PlatformGeoSelectionManager() {
079: super ();
080: partListener = new MapEditorPartListener();
081: initialize();
082: }
083:
084: private void initialize() {
085: if (!initialized) {
086: net.refractions.udig.ui.PlatformGIS
087: .syncInDisplayThread(new Runnable() {
088: public void run() {
089: IWorkbenchWindow ww = PlatformUI
090: .getWorkbench()
091: .getActiveWorkbenchWindow();
092: if (ww != null) {
093: IWorkbenchPage activePage = ww
094: .getActivePage();
095: if (activePage != null) {
096: activePage
097: .addPartListener(partListener);
098: initialized = true;
099:
100: LOGGER
101: .info("PlatformGeoSelectionManager is INITIALIZED.");
102:
103: Map activeMap = ApplicationGISInternal
104: .getActiveMap();
105: if (activeMap != null)
106: setCurrentMap(activeMap);
107: }
108: }
109:
110: }
111: });
112: }
113: }
114:
115: protected void setCurrentMap(Map activeMap) {
116: HashMap<String, IGeoSelectionEntry> selectionBag = (HashMap<String, IGeoSelectionEntry>) activeMap
117: .getBlackBoardInternal().get(PLATFORM_SELECTION_BAG);
118: if (selectionBag == null) {
119: selectionBag = new HashMap<String, IGeoSelectionEntry>();
120: activeMap.getBlackBoardInternal().put(
121: PLATFORM_SELECTION_BAG, selectionBag);
122:
123: cachedSelections = Collections.EMPTY_LIST;
124: } else {
125:
126: ArrayList<IGeoSelectionEntry> cache = new ArrayList<IGeoSelectionEntry>(
127: selectionBag.values());
128: cachedSelections = Collections.unmodifiableList(cache);
129: }
130:
131: this .currentMap = activeMap;
132: }
133:
134: private void clearSelections() {
135:
136: if (currentMap != null) {
137:
138: HashMap<String, IGeoSelectionEntry> selectionBag = (HashMap<String, IGeoSelectionEntry>) currentMap
139: .getBlackBoardInternal()
140: .get(PLATFORM_SELECTION_BAG);
141: for (Entry<String, IGeoSelectionEntry> entry : selectionBag
142: .entrySet()) {
143: String context = entry.getKey();
144: IGeoSelectionEntry selectionEntry = entry.getValue();
145:
146: IGeoSelection oldSelection = selectionEntry
147: .getSelection();
148: GeoSelectionChangedEvent<Map> event = new GeoSelectionChangedEvent<Map>(
149: context, currentMap, oldSelection, null);
150:
151: fireSelectionChanged(event);
152:
153: }
154:
155: cachedSelections = null;
156: currentMap = null;
157: latestGeoSelection = null;
158:
159: }
160: }
161:
162: protected Map getCurrentMap() {
163: return currentMap;
164: }
165:
166: /**
167: * @param context
168: * @param selection
169: */
170: public void setSelection(String context, IGeoSelection selection) {
171:
172: if (currentMap == null && !initialized) {
173: /**
174: * We need to initialize since during creation of manager the workbench
175: * was not ready at that moment.
176: */
177:
178: synchronized (this ) {
179: if (!initialized) {
180: initialize();
181: }
182: }
183:
184: }
185:
186: if (currentMap != null) {
187:
188: HashMap<String, IGeoSelectionEntry> selectionBag = (HashMap<String, IGeoSelectionEntry>) currentMap
189: .getBlackBoardInternal()
190: .get(PLATFORM_SELECTION_BAG);
191: GeoSelectionEntry entry = (GeoSelectionEntry) selectionBag
192: .get(context);
193:
194: IGeoSelection oldSelection = null;
195:
196: if (entry == null && selection != null) {
197: /*
198: * We need to create new IGeoSelectionEntry and reinitialize cache
199: * selection data structure.
200: */
201: entry = new GeoSelectionEntry(context);
202: entry.setSelection(selection);
203:
204: synchronized (this ) {
205: selectionBag.put(context, entry);
206: ArrayList<IGeoSelectionEntry> cache = new ArrayList<IGeoSelectionEntry>(
207: selectionBag.values());
208:
209: cachedSelections = Collections
210: .unmodifiableList(cache);
211: }
212:
213: } else if (entry != null && selection != null) {
214:
215: oldSelection = entry.getSelection();
216: entry.setSelection(selection);
217:
218: } else if (entry != null && selection == null) {
219:
220: oldSelection = entry.getSelection();
221: synchronized (this ) {
222: selectionBag.remove(context);
223: ArrayList<IGeoSelectionEntry> cache = new ArrayList<IGeoSelectionEntry>(
224: selectionBag.values());
225: cachedSelections = Collections
226: .unmodifiableList(cache);
227: }
228: }
229:
230: latestGeoSelection = (selection != null) ? entry : null;
231:
232: GeoSelectionChangedEvent<Map> event = new GeoSelectionChangedEvent<Map>(
233: context, currentMap, oldSelection, selection);
234:
235: fireSelectionChanged(event);
236:
237: } else {
238: LOGGER
239: .info("PlatformGeoSelectionManager: there is no active Map or manager is not initialized properly"); //$NON-NLS-1$
240: }
241: }
242:
243: /**
244: * Gets selection from current map by context.
245: *
246: * @param context
247: * @return
248: */
249: public IGeoSelection getSelection(String context) {
250: if (currentMap != null) {
251:
252: HashMap<String, IGeoSelectionEntry> selectionBag = (HashMap<String, IGeoSelectionEntry>) currentMap
253: .getBlackBoardInternal()
254: .get(PLATFORM_SELECTION_BAG);
255:
256: IGeoSelectionEntry entry = selectionBag.get(context);
257: if (entry == null)
258: return null;
259:
260: IGeoSelection selection = entry.getSelection();
261: return selection;
262: // Object selectionObj = selectionBag.get(context);
263: // if (selectionObj != null && selectionObj instanceof IGeoSelection) {
264: // IGeoSelection selection = (IGeoSelection) selectionObj;
265: // return selection;
266: // }
267: }
268: return null;
269: }
270:
271: /**
272: * Fires <code>GeoSelectionChangedEvent</code> to listeners.
273: *
274: * @param event
275: */
276: protected void fireSelectionChanged(GeoSelectionChangedEvent event) {
277:
278: LOGGER
279: .fine("PlatformGeoSelectionManager: new IGeoSelection is set and an event is fired to listeners"); //$NON-NLS-1$
280:
281: Object[] listenersArray = listeners.getListeners();
282:
283: for (Object listenerObj : listenersArray) {
284: try {
285: IGeoSelectionChangedListener listener = (IGeoSelectionChangedListener) listenerObj;
286: listener.geoSelectionChanged(event);
287:
288: } catch (Throwable t) {
289: LOGGER.log(Level.SEVERE, t.getMessage(), t);
290: }
291: }
292:
293: }
294:
295: /* (non-Javadoc)
296: * @see net.refractions.udig.project.geoselection.IGeoSelectionManager#getSelections()
297: */
298: public Iterator<IGeoSelectionEntry> getSelections() {
299: Iterator<IGeoSelectionEntry> it;
300: synchronized (this ) {
301: it = cachedSelections.iterator();
302: }
303: return it;
304: }
305:
306: class MapEditorPartListener implements IPartListener2 {
307:
308: // GeoSelectionManager selectionManager;
309:
310: // public GeoSelectionServicePartListener(GeoSelectionManager selectionManager){
311: // this.selectionManager = selectionManager;
312: // }
313:
314: public void partActivated(IWorkbenchPartReference partRef) {
315: if (partRef.getPart(false) instanceof MapEditor) {
316: Map activeMap = ((MapEditor) partRef.getPart(false))
317: .getMap();
318: PlatformGeoSelectionManager.this
319: .setCurrentMap(activeMap);
320: }
321: }
322:
323: public void partBroughtToTop(IWorkbenchPartReference partRef) {
324: // TODO Auto-generated method stub
325:
326: }
327:
328: public void partClosed(IWorkbenchPartReference partRef) {
329: if (partRef.getPart(false) instanceof MapEditor) {
330: System.out.println("MapEditor is closed");
331:
332: if (!PlatformUI.getWorkbench().isClosing()) {
333:
334: IEditorPart part = PlatformUI.getWorkbench()
335: .getActiveWorkbenchWindow().getActivePage()
336: .getActiveEditor();
337:
338: /*
339: * Means that the last MapEditor is being closed and we need
340: * to notify selection service listeners
341: * that there is no geoselection available.
342: */
343: if (part == null) {
344: LOGGER
345: .log(Level.FINE,
346: "The last MapEditor was closed. Notify listeners with NULL geoselection");
347: clearSelections();
348: }
349: }
350:
351: }
352:
353: }
354:
355: public void partDeactivated(IWorkbenchPartReference partRef) {
356: // TODO Auto-generated method stub
357:
358: }
359:
360: public void partHidden(IWorkbenchPartReference partRef) {
361: // TODO Auto-generated method stub
362:
363: }
364:
365: public void partInputChanged(IWorkbenchPartReference partRef) {
366: // TODO Auto-generated method stub
367:
368: }
369:
370: public void partOpened(IWorkbenchPartReference partRef) {
371: // TODO Auto-generated method stub
372:
373: }
374:
375: public void partVisible(IWorkbenchPartReference partRef) {
376: // TODO Auto-generated method stub
377:
378: }
379:
380: }
381:
382: public IGeoSelectionEntry getLatestSelection() {
383: return latestGeoSelection;
384: }
385:
386: }
|