]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.project/src/org/simantics/project/impl/Project.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.project / src / org / simantics / project / impl / Project.java
index d6929de34f2fbe5254fd2d5f9e03cb13aecdbb1b..7d507bbb2e37970088e14a329ab2f1d3c7267209 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.project.impl;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.Arrays;\r
-import java.util.LinkedList;\r
-import java.util.concurrent.atomic.AtomicBoolean;\r
-import java.util.concurrent.locks.Lock;\r
-import java.util.concurrent.locks.ReentrantLock;\r
-\r
-import org.simantics.db.RequestProcessor;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteOnlyGraph;\r
-import org.simantics.db.common.processor.MergingGraphRequestProcessor;\r
-import org.simantics.db.common.request.WriteOnlyRequest;\r
-import org.simantics.db.exception.CancelTransactionException;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.project.IProject;\r
-import org.simantics.project.exception.ProjectException;\r
-import org.simantics.project.features.IProjectFeature;\r
-import org.simantics.utils.datastructures.disposable.DisposeState;\r
-import org.simantics.utils.datastructures.disposable.IDisposeListener;\r
-import org.simantics.utils.datastructures.hints.HintContext;\r
-import org.simantics.utils.threads.IThreadWorkQueue;\r
-import org.simantics.utils.threads.SyncListenerList;\r
-\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class Project extends HintContext implements IProject {\r
-\r
-    private static IProjectFeature[]          NONE         = {};\r
-\r
-    //private static final String               TAG_PROJECTS = "projects";\r
-\r
-    private IProjectFeature[]                 features         = NONE;\r
-    private final LinkedList<IProjectFeature> featureSet       = new LinkedList<IProjectFeature>();\r
-    private final LinkedList<IProjectFeature> inactiveFeatures = new LinkedList<IProjectFeature>();\r
-    private final LinkedList<IProjectFeature> activeFeatures   = new LinkedList<IProjectFeature>();\r
-\r
-    private final Lock                        lock             = new ReentrantLock();\r
-    private final AtomicBoolean               active           = new AtomicBoolean(false);\r
-\r
-    protected Session                         session;\r
-    protected Resource                        resource;\r
-\r
-    public Project(Session session, Resource resource) {\r
-        if (session == null)\r
-            throw new NullPointerException("null session");\r
-        if (resource == null)\r
-            throw new NullPointerException("null resource");\r
-\r
-        this.session = session;\r
-        this.resource = resource;\r
-        //System.out.println("NEW PROJECT [" + resource.getResourceId() + "] (" + System.identityHashCode(this) + ")");\r
-    }\r
-\r
-    public void doDispose() {\r
-        //System.out.println("DISPOSE: " + this + " (" + System.identityHashCode(this) + ")");\r
-        lock.lock();\r
-        try {\r
-            deactivate();\r
-\r
-            featureSet.clear();\r
-            features = NONE;\r
-        } catch (ProjectException e1) {\r
-            // TODO: do something more sensible than print the possible exception!\r
-            e1.printStackTrace();\r
-        } finally {\r
-            lock.unlock();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public IProjectFeature[] getFeatures() {\r
-        assertNotDisposed();\r
-\r
-        // Defensive copy.\r
-        IProjectFeature[] features = this.features;\r
-        return Arrays.copyOf(features, features.length);\r
-    }\r
-\r
-    public void addFeature(IProjectFeature feature) {\r
-        assertNotDisposed();\r
-        lock.lock();\r
-        try {\r
-            if (!featureSet.contains(feature)) {\r
-                featureSet.add(feature);\r
-                inactiveFeatures.add(feature);\r
-                features = featureSet.toArray(new IProjectFeature[featureSet.size()]);\r
-            }\r
-        } finally {\r
-            lock.unlock();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void activate() throws ProjectException {\r
-        if (isDisposed())\r
-            throw new IllegalStateException("project is disposed, cannot activate " + this + " (" + System.identityHashCode(this) + ")");\r
-\r
-        lock.lock();\r
-        try {\r
-            if (active.get() == true)\r
-                return;\r
-\r
-            while (!inactiveFeatures.isEmpty()) {\r
-                IProjectFeature feature = inactiveFeatures.getFirst();\r
-                boolean success = false;\r
-                try {\r
-                    feature.setProjectElement(this);\r
-                    feature.configure();\r
-\r
-                    inactiveFeatures.removeFirst();\r
-                    activeFeatures.addLast(feature);\r
-\r
-                    success = true;\r
-                } finally {\r
-                    if (!success)\r
-                        feature.setProjectElement(null);\r
-                }\r
-            }\r
-\r
-            try {\r
-                transactionBarrier();\r
-            } finally {\r
-                active.set(true);\r
-            }\r
-        } finally {\r
-            lock.unlock();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void deactivate() throws ProjectException {\r
-        if (isDisposed())\r
-            throw new IllegalStateException("project is disposed, cannot deactivate " + this + " (" + System.identityHashCode(this) + ")");\r
-\r
-        lock.lock();\r
-        try {\r
-            if (active.get() == false)\r
-                return;\r
-\r
-            while (!activeFeatures.isEmpty()) {\r
-                IProjectFeature feature = activeFeatures.getLast();\r
-                boolean success = false;\r
-                try {\r
-                    feature.deconfigure();\r
-\r
-                    activeFeatures.removeLast();\r
-                    inactiveFeatures.addFirst(feature);\r
-\r
-                    success = true;\r
-                } finally {\r
-                    if (success)\r
-                        feature.setProjectElement(null);\r
-                }\r
-            }\r
-\r
-            try {\r
-                transactionBarrier();\r
-            } finally {\r
-                active.set(false);\r
-            }\r
-        } finally {\r
-            lock.unlock();\r
-        }\r
-    }\r
-\r
-    private void transactionBarrier() throws ProjectException {\r
-        // IMPORTANT: ensure that all database requests have been\r
-        // completed before returning from deactivation.\r
-        try {\r
-            session.syncRequest(new WriteOnlyRequest() {\r
-                @Override\r
-                public void perform(WriteOnlyGraph graph) throws DatabaseException {\r
-                    throw new CancelTransactionException("barrier");\r
-                }\r
-            });\r
-        } catch (CancelTransactionException e) {\r
-        } catch (DatabaseException e) {\r
-            throw new ProjectException(e);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public String toString() {\r
-        return getClass().getSimpleName() + " [resource=" + get().getResourceId() + "]";\r
-    }\r
-\r
-    @Override\r
-    public int hashCode() {\r
-        return get().hashCode();\r
-    }\r
-\r
-    @Override\r
-    public boolean equals(Object obj) {\r
-        if (this == obj)\r
-            return true;\r
-        if (!(obj instanceof Project))\r
-            return false;\r
-        final Project other = (Project) obj;\r
-\r
-        // Need to make sure that the resources are from the same session.\r
-        if (!session.equals(other.session))\r
-            return false;\r
-\r
-        Resource r1 = get();\r
-        Resource r2 = other.get();\r
-        if (r1 == null) {\r
-            if (r2 != null)\r
-                return false;\r
-        } else if (!r1.equals(r2))\r
-            return false;\r
-\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public Session getSession() {\r
-        return session;\r
-    }\r
-\r
-    @Override\r
-    public Resource get() {\r
-        return resource;\r
-    }\r
-\r
-    public RequestProcessor getGraphRequestProcessor() {\r
-        MergingGraphRequestProcessor mgrp = session.peekService(MergingGraphRequestProcessor.class);\r
-        return mgrp != null ? mgrp : session;\r
-    }\r
-\r
-    // IDisposable implementation (copied from AbstractDisposable)\r
-\r
-    SyncListenerList<IDisposeListener> disposeListeners = null;\r
-\r
-    private volatile DisposeState disposeStatus = DisposeState.Alive;\r
-\r
-    protected void assertNotDisposed() {\r
-        if (isDisposed())\r
-            throw new IllegalStateException(this + " is disposed");\r
-    }\r
-\r
-    @Override\r
-    public DisposeState getDisposeState() {\r
-        return disposeStatus;\r
-    }\r
-\r
-    @Override\r
-    public boolean isDisposed() {\r
-        return disposeStatus == DisposeState.Disposed;\r
-    }\r
-\r
-    public boolean isAlive() {\r
-        return disposeStatus == DisposeState.Alive;\r
-    }\r
-\r
-    @Override\r
-    public void dispose() {\r
-        try {\r
-            lock.lock();\r
-            try {\r
-                if (disposeStatus == DisposeState.Disposing)\r
-                    return;\r
-                assertNotDisposed();\r
-                disposeStatus = DisposeState.Disposing;\r
-            } finally {\r
-                lock.unlock();\r
-            }\r
-\r
-            try {\r
-                fireDisposed();\r
-            } finally {\r
-                doDispose();\r
-            }\r
-        } finally {\r
-            disposeStatus = DisposeState.Disposed;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Disposes if not disposed\r
-     */\r
-    @Override\r
-    public void safeDispose() {\r
-        try {\r
-            lock.lock();\r
-            try {\r
-                if (disposeStatus != DisposeState.Alive)\r
-                    return;\r
-                disposeStatus = DisposeState.Disposing;\r
-            } finally {\r
-                lock.unlock();\r
-            }\r
-\r
-            try {\r
-                fireDisposed();\r
-            } finally {\r
-                doDispose();\r
-            }\r
-        } finally {\r
-            disposeStatus = DisposeState.Disposed;\r
-        }\r
-    }\r
-\r
-    protected boolean hasDisposeListeners() {\r
-        return disposeListeners!=null && !disposeListeners.isEmpty();\r
-    }\r
-\r
-    private final static Method onDisposed = SyncListenerList.getMethod(IDisposeListener.class, "onDisposed");\r
-\r
-    private void fireDisposed() {\r
-        if (disposeListeners==null) return;\r
-        disposeListeners.fireEventSync(onDisposed, this);\r
-    }\r
-\r
-    @SuppressWarnings("unused")\r
-    private void fireDisposedAsync() {\r
-        if (disposeListeners==null) return;\r
-        disposeListeners.fireEventAsync(onDisposed, this);\r
-    }\r
-\r
-    @Override\r
-    public void addDisposeListener(IDisposeListener listener) {\r
-        lazyGetListenerList().add(listener);\r
-    }\r
-\r
-    @Override\r
-    public void addDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) {\r
-        lazyGetListenerList().add(thread, listener);\r
-    }\r
-\r
-    @Override\r
-    public void removeDisposeListener(IDisposeListener listener) {\r
-        if (disposeListeners==null) return;\r
-        disposeListeners.remove(listener);\r
-    }\r
-\r
-    @Override\r
-    public void removeDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) {\r
-        if (disposeListeners==null) return;\r
-        disposeListeners.remove(thread, listener);\r
-    }\r
-\r
-    private synchronized SyncListenerList<IDisposeListener> lazyGetListenerList() {\r
-        if (disposeListeners==null)\r
-            disposeListeners = new SyncListenerList<IDisposeListener>(IDisposeListener.class);\r
-        return disposeListeners;\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.project.impl;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteOnlyGraph;
+import org.simantics.db.common.processor.MergingGraphRequestProcessor;
+import org.simantics.db.common.request.WriteOnlyRequest;
+import org.simantics.db.exception.CancelTransactionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.project.IProject;
+import org.simantics.project.exception.ProjectException;
+import org.simantics.project.features.IProjectFeature;
+import org.simantics.utils.datastructures.disposable.DisposeState;
+import org.simantics.utils.datastructures.disposable.IDisposeListener;
+import org.simantics.utils.datastructures.hints.HintContext;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.SyncListenerList;
+
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class Project extends HintContext implements IProject {
+
+    private static IProjectFeature[]          NONE         = {};
+
+    //private static final String               TAG_PROJECTS = "projects";
+
+    private IProjectFeature[]                 features         = NONE;
+    private final LinkedList<IProjectFeature> featureSet       = new LinkedList<IProjectFeature>();
+    private final LinkedList<IProjectFeature> inactiveFeatures = new LinkedList<IProjectFeature>();
+    private final LinkedList<IProjectFeature> activeFeatures   = new LinkedList<IProjectFeature>();
+
+    private final Lock                        lock             = new ReentrantLock();
+    private final AtomicBoolean               active           = new AtomicBoolean(false);
+
+    protected Session                         session;
+    protected Resource                        resource;
+
+    public Project(Session session, Resource resource) {
+        if (session == null)
+            throw new NullPointerException("null session");
+        if (resource == null)
+            throw new NullPointerException("null resource");
+
+        this.session = session;
+        this.resource = resource;
+        //System.out.println("NEW PROJECT [" + resource.getResourceId() + "] (" + System.identityHashCode(this) + ")");
+    }
+
+    public void doDispose() {
+        //System.out.println("DISPOSE: " + this + " (" + System.identityHashCode(this) + ")");
+        lock.lock();
+        try {
+            deactivate();
+
+            featureSet.clear();
+            features = NONE;
+        } catch (ProjectException e1) {
+            // TODO: do something more sensible than print the possible exception!
+            e1.printStackTrace();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public IProjectFeature[] getFeatures() {
+        assertNotDisposed();
+
+        // Defensive copy.
+        IProjectFeature[] features = this.features;
+        return Arrays.copyOf(features, features.length);
+    }
+
+    public void addFeature(IProjectFeature feature) {
+        assertNotDisposed();
+        lock.lock();
+        try {
+            if (!featureSet.contains(feature)) {
+                featureSet.add(feature);
+                inactiveFeatures.add(feature);
+                features = featureSet.toArray(new IProjectFeature[featureSet.size()]);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public void activate() throws ProjectException {
+        if (isDisposed())
+            throw new IllegalStateException("project is disposed, cannot activate " + this + " (" + System.identityHashCode(this) + ")");
+
+        lock.lock();
+        try {
+            if (active.get() == true)
+                return;
+
+            while (!inactiveFeatures.isEmpty()) {
+                IProjectFeature feature = inactiveFeatures.getFirst();
+                boolean success = false;
+                try {
+                    feature.setProjectElement(this);
+                    feature.configure();
+
+                    inactiveFeatures.removeFirst();
+                    activeFeatures.addLast(feature);
+
+                    success = true;
+                } finally {
+                    if (!success)
+                        feature.setProjectElement(null);
+                }
+            }
+
+            try {
+                transactionBarrier();
+            } finally {
+                active.set(true);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public void deactivate() throws ProjectException {
+        if (isDisposed())
+            throw new IllegalStateException("project is disposed, cannot deactivate " + this + " (" + System.identityHashCode(this) + ")");
+
+        lock.lock();
+        try {
+            if (active.get() == false)
+                return;
+
+            while (!activeFeatures.isEmpty()) {
+                IProjectFeature feature = activeFeatures.getLast();
+                boolean success = false;
+                try {
+                    feature.deconfigure();
+
+                    activeFeatures.removeLast();
+                    inactiveFeatures.addFirst(feature);
+
+                    success = true;
+                } finally {
+                    if (success)
+                        feature.setProjectElement(null);
+                }
+            }
+
+            try {
+                transactionBarrier();
+            } finally {
+                active.set(false);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    private void transactionBarrier() throws ProjectException {
+        // IMPORTANT: ensure that all database requests have been
+        // completed before returning from deactivation.
+        try {
+            session.syncRequest(new WriteOnlyRequest() {
+                @Override
+                public void perform(WriteOnlyGraph graph) throws DatabaseException {
+                    throw new CancelTransactionException("barrier");
+                }
+            });
+        } catch (CancelTransactionException e) {
+        } catch (DatabaseException e) {
+            throw new ProjectException(e);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " [resource=" + get().getResourceId() + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return get().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof Project))
+            return false;
+        final Project other = (Project) obj;
+
+        // Need to make sure that the resources are from the same session.
+        if (!session.equals(other.session))
+            return false;
+
+        Resource r1 = get();
+        Resource r2 = other.get();
+        if (r1 == null) {
+            if (r2 != null)
+                return false;
+        } else if (!r1.equals(r2))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public Session getSession() {
+        return session;
+    }
+
+    @Override
+    public Resource get() {
+        return resource;
+    }
+
+    public RequestProcessor getGraphRequestProcessor() {
+        MergingGraphRequestProcessor mgrp = session.peekService(MergingGraphRequestProcessor.class);
+        return mgrp != null ? mgrp : session;
+    }
+
+    // IDisposable implementation (copied from AbstractDisposable)
+
+    SyncListenerList<IDisposeListener> disposeListeners = null;
+
+    private volatile DisposeState disposeStatus = DisposeState.Alive;
+
+    protected void assertNotDisposed() {
+        if (isDisposed())
+            throw new IllegalStateException(this + " is disposed");
+    }
+
+    @Override
+    public DisposeState getDisposeState() {
+        return disposeStatus;
+    }
+
+    @Override
+    public boolean isDisposed() {
+        return disposeStatus == DisposeState.Disposed;
+    }
+
+    public boolean isAlive() {
+        return disposeStatus == DisposeState.Alive;
+    }
+
+    @Override
+    public void dispose() {
+        try {
+            lock.lock();
+            try {
+                if (disposeStatus == DisposeState.Disposing)
+                    return;
+                assertNotDisposed();
+                disposeStatus = DisposeState.Disposing;
+            } finally {
+                lock.unlock();
+            }
+
+            try {
+                fireDisposed();
+            } finally {
+                doDispose();
+            }
+        } finally {
+            disposeStatus = DisposeState.Disposed;
+        }
+    }
+
+    /**
+     * Disposes if not disposed
+     */
+    @Override
+    public void safeDispose() {
+        try {
+            lock.lock();
+            try {
+                if (disposeStatus != DisposeState.Alive)
+                    return;
+                disposeStatus = DisposeState.Disposing;
+            } finally {
+                lock.unlock();
+            }
+
+            try {
+                fireDisposed();
+            } finally {
+                doDispose();
+            }
+        } finally {
+            disposeStatus = DisposeState.Disposed;
+        }
+    }
+
+    protected boolean hasDisposeListeners() {
+        return disposeListeners!=null && !disposeListeners.isEmpty();
+    }
+
+    private final static Method onDisposed = SyncListenerList.getMethod(IDisposeListener.class, "onDisposed");
+
+    private void fireDisposed() {
+        if (disposeListeners==null) return;
+        disposeListeners.fireEventSync(onDisposed, this);
+    }
+
+    @SuppressWarnings("unused")
+    private void fireDisposedAsync() {
+        if (disposeListeners==null) return;
+        disposeListeners.fireEventAsync(onDisposed, this);
+    }
+
+    @Override
+    public void addDisposeListener(IDisposeListener listener) {
+        lazyGetListenerList().add(listener);
+    }
+
+    @Override
+    public void addDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) {
+        lazyGetListenerList().add(thread, listener);
+    }
+
+    @Override
+    public void removeDisposeListener(IDisposeListener listener) {
+        if (disposeListeners==null) return;
+        disposeListeners.remove(listener);
+    }
+
+    @Override
+    public void removeDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) {
+        if (disposeListeners==null) return;
+        disposeListeners.remove(thread, listener);
+    }
+
+    private synchronized SyncListenerList<IDisposeListener> lazyGetListenerList() {
+        if (disposeListeners==null)
+            disposeListeners = new SyncListenerList<IDisposeListener>(IDisposeListener.class);
+        return disposeListeners;
+    }
+
+}