001: /**
002: * <copyright></copyright> $Id: ProjectImpl.java 22687 2006-11-10 20:55:33Z jeichar $
003: */package net.refractions.udig.project.internal.impl;
004:
005: import java.io.File;
006: import java.util.ArrayList;
007: import java.util.Collection;
008: import java.util.Collections;
009: import java.util.Iterator;
010: import java.util.List;
011:
012: import net.refractions.udig.project.command.Command;
013: import net.refractions.udig.project.command.CommandManager;
014: import net.refractions.udig.project.internal.Map;
015: import net.refractions.udig.project.internal.Messages;
016: import net.refractions.udig.project.internal.Project;
017: import net.refractions.udig.project.internal.ProjectElement;
018: import net.refractions.udig.project.internal.ProjectPackage;
019: import net.refractions.udig.project.internal.commands.DefaultErrorHandler;
020:
021: import org.eclipse.core.runtime.Platform;
022: import org.eclipse.emf.common.notify.Adapter;
023: import org.eclipse.emf.common.notify.Notification;
024: import org.eclipse.emf.common.notify.NotificationChain;
025: import org.eclipse.emf.common.notify.impl.AdapterImpl;
026: import org.eclipse.emf.common.notify.impl.NotificationChainImpl;
027: import org.eclipse.emf.common.util.EList;
028: import org.eclipse.emf.common.util.URI;
029: import org.eclipse.emf.ecore.EClass;
030: import org.eclipse.emf.ecore.EObject;
031: import org.eclipse.emf.ecore.EStructuralFeature;
032: import org.eclipse.emf.ecore.InternalEObject;
033: import org.eclipse.emf.ecore.impl.ENotificationImpl;
034: import org.eclipse.emf.ecore.impl.EObjectImpl;
035: import org.eclipse.emf.ecore.resource.Resource;
036: import org.eclipse.emf.ecore.resource.URIConverter;
037: import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
038: import org.eclipse.emf.ecore.util.InternalEList;
039:
040: /**
041: * Default implementation
042: *
043: * @author Jesse
044: * @since 1.0.0
045: */
046: public class ProjectImpl extends EObjectImpl implements Project {
047:
048: /**
049: * The default value of the '{@link #getName() <em>Name</em>}' attribute. <!-- begin-user-doc
050: * --> <!-- end-user-doc -->
051: *
052: * @see #getName()
053: * @generated NOT
054: * @ordered
055: */
056: protected static final String NAME_EDEFAULT = ""; //$NON-NLS-1$
057:
058: /**
059: * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
060: * <!-- begin-user-doc
061: * --> <!-- end-user-doc -->
062: * @see #getName()
063: * @generated
064: * @ordered
065: */
066: protected String name = NAME_EDEFAULT;
067:
068: /**
069: * The cached value of the '{@link #getElementsInternal() <em>Elements Internal</em>}' reference list.
070: * <!-- begin-user-doc --> <!-- end-user-doc -->
071: * @see #getElementsInternal()
072: * @generated
073: * @ordered
074: */
075: protected EList elementsInternal = null;
076:
077: private Adapter projectPersistenceListener = new AdapterImpl() {
078: /**
079: * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
080: */
081: public void notifyChanged(Notification msg) {
082: switch (msg.getFeatureID(Project.class)) {
083: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
084: case ProjectPackage.PROJECT__NAME:
085: if (ProjectImpl.this .eResource() != null)
086: ProjectImpl.this .eResource().setModified(true);
087: }
088: }
089: };
090:
091: /**
092: * <!-- begin-user-doc --> <!-- end-user-doc -->
093: *
094: * @generated NOT
095: */
096: @SuppressWarnings("unchecked")
097: protected ProjectImpl() {
098: super ();
099: eAdapters().add(projectPersistenceListener);
100: }
101:
102: /**
103: * <!-- begin-user-doc --> <!-- end-user-doc -->
104: * @generated
105: */
106: protected EClass eStaticClass() {
107: return ProjectPackage.eINSTANCE.getProject();
108: }
109:
110: /**
111: * <!-- begin-user-doc --> <!-- end-user-doc -->
112: * @generated
113: */
114: public String getName() {
115: return name;
116: }
117:
118: /**
119: * <!-- begin-user-doc --> <!-- end-user-doc -->
120: * @generated
121: */
122: public void setName(String newName) {
123: String oldName = name;
124: name = newName;
125: if (eNotificationRequired())
126: eNotify(new ENotificationImpl(this , Notification.SET,
127: ProjectPackage.PROJECT__NAME, oldName, name));
128: }
129:
130: /**
131: * <!-- begin-user-doc --> <!-- end-user-doc -->
132: * @generated not
133: */
134: @SuppressWarnings("unchecked")
135: public List getElementsInternal() {
136: if (elementsInternal == null) {
137: elementsInternal = new SynchronizedEObjectWithInverseResolvingEList(
138: ProjectElement.class, this ,
139: ProjectPackage.PROJECT__ELEMENTS_INTERNAL,
140: ProjectPackage.PROJECT_ELEMENT__PROJECT_INTERNAL) {
141:
142: /** long serialVersionUID field */
143: private static final long serialVersionUID = 3978658123285628492L;
144:
145: @Override
146: protected void didAdd(int index, Object newObject) {
147: createResourceAndAddElement(ProjectImpl.this ,
148: (ProjectElement) newObject);
149: super .didAdd(index, newObject);
150: }
151:
152: @Override
153: protected void didSet(int index, Object newObject,
154: Object oldObject) {
155: createResourceAndAddElement(ProjectImpl.this ,
156: (ProjectElement) newObject);
157: super .didSet(index, newObject, oldObject);
158: }
159: };
160: }
161: return elementsInternal;
162: }
163:
164: /**
165: * <!-- begin-user-doc --> <!-- end-user-doc -->
166: *
167: * @generated NOT
168: */
169: @SuppressWarnings("unchecked")
170: public List getElements(Class type) {
171: List lists = new ArrayList();
172: for (Iterator iter = getElementsInternal().iterator(); iter
173: .hasNext();) {
174: Object obj = iter.next();
175: if (type.isAssignableFrom(obj.getClass()))
176: lists.add(obj);
177: }
178: return lists;
179: }
180:
181: public NotificationChain eInverseAdd(InternalEObject otherEnd,
182: int featureID, Class baseClass, NotificationChain msgs) {
183:
184: /*
185: * Reason for comment:
186: * During map creation, both this method and add seem to be called, but
187: * the resource should only ever be created once.
188: *
189: * createResourceAndAddElement(this, (ProjectElement) otherEnd);
190: */
191: return eInverseAddGen(otherEnd, featureID, baseClass, msgs);
192: }
193:
194: /**
195: * <!-- begin-user-doc --> <!-- end-user-doc -->
196: * @generated
197: */
198: public NotificationChain eInverseAddGen(InternalEObject otherEnd,
199: int featureID, Class baseClass, NotificationChain msgs) {
200: if (featureID >= 0) {
201: switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
202: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
203: return ((InternalEList) getElementsInternal())
204: .basicAdd(otherEnd, msgs);
205: default:
206: return eDynamicInverseAdd(otherEnd, featureID,
207: baseClass, msgs);
208: }
209: }
210: if (eContainer != null)
211: msgs = eBasicRemoveFromContainer(msgs);
212: return eBasicSetContainer(otherEnd, featureID, msgs);
213: }
214:
215: /**
216: * <!-- begin-user-doc --> <!-- end-user-doc -->
217: * @generated
218: */
219: public NotificationChain eInverseRemove(InternalEObject otherEnd,
220: int featureID, Class baseClass, NotificationChain msgs) {
221: if (featureID >= 0) {
222: switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
223: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
224: return ((InternalEList) getElementsInternal())
225: .basicRemove(otherEnd, msgs);
226: default:
227: return eDynamicInverseRemove(otherEnd, featureID,
228: baseClass, msgs);
229: }
230: }
231: return eBasicSetContainer(null, featureID, msgs);
232: }
233:
234: /**
235: * <!-- begin-user-doc --> <!-- end-user-doc -->
236: * @generated
237: */
238: public Object eGet(EStructuralFeature eFeature, boolean resolve) {
239: switch (eDerivedStructuralFeatureID(eFeature)) {
240: case ProjectPackage.PROJECT__NAME:
241: return getName();
242: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
243: return getElementsInternal();
244: }
245: return eDynamicGet(eFeature, resolve);
246: }
247:
248: /**
249: * <!-- begin-user-doc --> <!-- end-user-doc -->
250: * @generated
251: */
252: @SuppressWarnings("unchecked")
253: public void eSet(EStructuralFeature eFeature, Object newValue) {
254: switch (eDerivedStructuralFeatureID(eFeature)) {
255: case ProjectPackage.PROJECT__NAME:
256: setName((String) newValue);
257: return;
258: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
259: getElementsInternal().clear();
260: getElementsInternal().addAll((Collection) newValue);
261: return;
262: }
263: eDynamicSet(eFeature, newValue);
264: }
265:
266: /**
267: * <!-- begin-user-doc --> <!-- end-user-doc -->
268: * @generated
269: */
270: public void eUnset(EStructuralFeature eFeature) {
271: switch (eDerivedStructuralFeatureID(eFeature)) {
272: case ProjectPackage.PROJECT__NAME:
273: setName(NAME_EDEFAULT);
274: return;
275: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
276: getElementsInternal().clear();
277: return;
278: }
279: eDynamicUnset(eFeature);
280: }
281:
282: /**
283: * <!-- begin-user-doc --> <!-- end-user-doc -->
284: * @generated
285: */
286: public boolean eIsSet(EStructuralFeature eFeature) {
287: switch (eDerivedStructuralFeatureID(eFeature)) {
288: case ProjectPackage.PROJECT__NAME:
289: return NAME_EDEFAULT == null ? name != null
290: : !NAME_EDEFAULT.equals(name);
291: case ProjectPackage.PROJECT__ELEMENTS_INTERNAL:
292: return elementsInternal != null
293: && !elementsInternal.isEmpty();
294: }
295: return eDynamicIsSet(eFeature);
296: }
297:
298: /**
299: * <!-- begin-user-doc --> <!-- end-user-doc -->
300: * @generated
301: */
302: public String toString() {
303: if (eIsProxy())
304: return super .toString();
305:
306: StringBuffer result = new StringBuffer(super .toString());
307: result.append(" (name: "); //$NON-NLS-1$
308: result.append(name);
309: result.append(')');
310: return result.toString();
311: }
312:
313: CommandManager commandManager;
314:
315: /**
316: * @see net.refractions.udig.project.IProject#getElements()
317: */
318: @SuppressWarnings("unchecked")
319: public List getElements() {
320: return Collections.unmodifiableList(getElementsInternal());
321: }
322:
323: private void initCommandManager() {
324:
325: synchronized (CommandManager.class) {
326: if (commandManager == null) {
327: commandManager = new CommandManager(
328: Messages.ProjectImpl_commandManagerName,
329: new DefaultErrorHandler());
330: }
331: }
332: }
333:
334: public void sendASync(Command command) {
335: initCommandManager();
336: commandManager.aSyncExecute(command);
337: }
338:
339: public void sendSync(Command command) {
340: initCommandManager();
341: commandManager.syncExecute(command);
342: }
343:
344: // Executor executor = new Executor(Messages.ProjectImpl_executor);
345: //
346: // /**
347: // * <!-- begin-user-doc --> <!-- end-user-doc -->
348: // *
349: // * @generated NOT
350: // */
351: // public void send( Command command, boolean async ) {
352: // executor.addCommand(command);
353: // executor.schedule();
354: //
355: // if (!async) {
356: // try {
357: // // wait
358: // while( true ) {
359: // synchronized (command) {
360: // command.wait(100);
361: // }
362: //
363: // if (!executor.commands.contains(command))
364: // break;
365: // }
366: // } catch (InterruptedException e) {
367: // // TODO: log this
368: // projectUI
369: // }
370: // }
371: // }
372: //
373: // public void sendASync( Command command ) {
374: // send(command, true);
375: // }
376: //
377: // public void sendSync( Command command ) {
378: // send(command, false);
379: // }
380: //
381: // /**
382: // * Executes a command.
383: // *
384: // * @author jeichar
385: // * @since 0.9.0
386: // */
387: // public class Executor extends Job {
388: //
389: // private Stack<Command> commands = new Stack<Command>();
390: //
391: // /**
392: // * Construct <code>Executor</code>.
393: // *
394: // * @param name the name of the job
395: // */
396: // public Executor( String name ) {
397: // super(name);
398: // setSystem(true);
399: // setPriority(LONG);
400: // }
401: //
402: // @Override
403: // protected IStatus run( IProgressMonitor monitor ) {
404: // Command command;
405: // while( !commands.isEmpty() ) {
406: // command = commands.peek();
407: // execute(command, monitor);
408: //
409: // synchronized (this) {
410: // commands.pop();
411: // }
412: // synchronized (command) {
413: // command.notifyAll();
414: // }
415: //
416: // break;
417: // }
418: // return Status.OK_STATUS;
419: // }
420: //
421: // /**
422: // * Adds a command to the stack of commands that needs to be executed.
423: // *
424: // * @param command
425: // */
426: // public synchronized void addCommand( Command command ) {
427: // commands.push(command);
428: // }
429: //
430: // /**
431: // * Executes a command. Calls the Errorhandler if an exception is thrown.
432: // *
433: // * @param command The command to execute
434: // * @param monitor The progress monitor.
435: // */
436: // public void execute( final Command command, IProgressMonitor monitor ) {
437: // try {
438: // command.run(monitor);
439: // } catch (Exception e) {
440: // ProjectPlugin.log(null, e);
441: // }
442: // }
443: //
444: // }
445:
446: /**
447: * Creates a new Resource from map. The new Resource will be in the same directory as the project's
448: * resource. The Resource will start with map appended with a number that will make the name unique.
449: * The resource will end in .umap.
450: */
451: private void createResourceAndAddElement(Project value,
452: ProjectElement projectElement) {
453: if (projectElement == null || projectElement.eIsProxy())
454: return;
455: Resource projectResource = eResource();
456: if (projectResource != null) {
457: URI projectURI = projectResource.getURI();
458: String elementPath = null;
459: elementPath = findElementResourcePath(projectElement,
460: elementPath);
461:
462: String projectPath = findProjectResourcePath(projectURI);
463:
464: if (!projectPath.equals(elementPath))
465: doCreation(projectElement, projectResource,
466: elementPath, projectPath);
467:
468: // if( projectElement.getProjectInternal()!=this && projectElement instanceof InternalEObject ){
469: // InternalEObject object=(InternalEObject) projectElement;
470: // object.eInverseAdd(this, ProjectPackage.MAP__PROJECT_INTERNAL,
471: // Map.class, new NotificationChainImpl());
472: // }
473:
474: }
475: }
476:
477: @SuppressWarnings("unchecked")
478: private void doCreation(ProjectElement projectElement,
479: Resource projectResource, String elementPath,
480: String projectPath) {
481: Resource resource = null;
482:
483: URI uri = createNewResource(projectResource, projectPath,
484: projectElement);
485: resource = projectResource.getResourceSet().createResource(uri);
486: resource.getContents().add(projectElement);
487: resource.setTrackingModification(true);
488: resource.setModified(true);
489: }
490:
491: private String findProjectResourcePath(URI projectURI) {
492: String projectPath = projectURI.toFileString();
493: projectPath = projectPath.substring(0, projectPath
494: .lastIndexOf(File.separatorChar));
495: while (projectPath.startsWith(File.separator + File.separator)) {
496: projectPath = projectPath.substring(1);
497: }
498: if (Platform.getOS().equals(Platform.OS_WIN32)
499: && projectPath.startsWith(File.separator)) {
500: projectPath = projectPath.substring(1);
501: }
502: return projectPath;
503: }
504:
505: private String findElementResourcePath(
506: ProjectElement projectElement, String elementPath2) {
507: String elementPath = elementPath2;
508: if (projectElement.eResource() != null) {
509: elementPath = projectElement.eResource().getURI()
510: .toFileString();
511: elementPath = elementPath.substring(0, elementPath
512: .lastIndexOf(File.separatorChar));
513: while (elementPath.startsWith(File.separator
514: + File.separator)) {
515: elementPath = elementPath.substring(1);
516: }
517: if (Platform.getOS().equals(Platform.OS_WIN32)
518: && elementPath.startsWith(File.separator)) {
519: elementPath = elementPath.substring(1);
520: }
521: }
522: return elementPath;
523: }
524:
525: @SuppressWarnings("unchecked")
526: private URI createNewResource(Resource projectResource,
527: String projectPath, ProjectElement projectElement) {
528: int i = 0;
529: List<Resource> list = projectResource.getResourceSet()
530: .getResources();
531: URIConverter uriConverter = projectResource.getResourceSet()
532: .getURIConverter();
533: URI uri = null;
534: boolean found = false;
535: do {
536: found = false;
537: i++;
538: for (Resource resource2 : list) {
539: //TODO Add file extension name to ProjectElement
540: String resourceName = (projectElement.getName() == null ? "element" : projectElement.getName()) + i; //$NON-NLS-1$
541: String extension = projectElement.getFileExtension();
542: if (!extension.startsWith(".")) //$NON-NLS-1$
543: extension = "." + extension; //$NON-NLS-1$
544: String tempPath = "file://" + projectPath + File.separator + resourceName + extension; //$NON-NLS-1$
545: uri = URI.createURI(tempPath);
546: URI normalizedURI = uriConverter.normalize(uri);
547: if (uriConverter.normalize(resource2.getURI()).equals(
548: normalizedURI)) {
549: found = true;
550: break;
551: }
552: }
553: if (!found) {
554: File file = new File(uri.toFileString());
555: if (file.exists())
556: found = true;
557: }
558: } while (found);
559: return uri;
560: }
561:
562: public URI getID() {
563: if (eResource() == null)
564: return URI.createFileURI(getName());
565: return eResource().getURI();
566: }
567:
568: @Override
569: public EObject eResolveProxy(InternalEObject proxy) {
570: EObject resolvedElement = super .eResolveProxy(proxy);
571: // if( resolvedElement instanceof ProjectElement ){
572: // ProjectElement element=(ProjectElement) resolvedElement;
573: // element.setProjectInternal(this);
574: // return element;
575: // }else{
576: // String string = "Resolved element of project:"+getName()+" is not a ProjectElement!"; //$NON-NLS-1$ //$NON-NLS-2$
577: // IllegalArgumentException illegalArgumentException = new IllegalArgumentException(string);
578: // ProjectPlugin.log(string, illegalArgumentException);
579: // throw illegalArgumentException;
580: // }
581: return resolvedElement;
582: }
583: } // ProjectImpl
|