]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceInputViewPart.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / workbench / ResourceInputViewPart.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.ui.workbench;
13
14 import org.eclipse.swt.widgets.Composite;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.event.ChangeEvent;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.layer0.Layer0;
20 import org.simantics.utils.ui.ErrorLogger;
21 import org.simantics.utils.ui.workbench.WorkbenchUtils;
22
23 /**
24  * This class inherits the Graph access setup behavior from
25  * GraphAccessViewPart and in addition assumes that the view receives a
26  * Resource ID as a parameter in the secondary ID of the view part.
27  * 
28  * <p>
29  * To use this class all you need to do is call super.createPartControl in your
30  * own createPartControl implementation. This will make sure a {@link Graph}
31  * will be available directly after that for initializing the UI and its
32  * contents.
33  * </p>
34  * 
35  * <p>
36  * To open a ResourceInputViewPart use:
37  * {@link ResourceViewPartUtils#activateViewForResource(String, org.simantics.db.Session, Resource)}</code>
38  * which should give the view the specified resource id as its secondary id.
39  * </p>
40  * 
41  * @author Tuukka Lehtonen
42  */
43 public abstract class ResourceInputViewPart extends GraphAccessViewPart {
44
45     private static final String NO_NAME        = "(no name)";
46
47     private static final String MULTIPLE_NAMES = "(multiple names)";
48
49
50     private ResourceInput       mainInput;
51
52     private Resource            inputResource;
53
54     private String              inputName      = NO_NAME;
55
56
57     //----------------------------------------------------------------------
58     // Getters
59
60     public Resource getInputResource() {
61         return inputResource;
62     }
63
64     public String getInputName() {
65         return inputName;
66     }
67
68
69     //----------------------------------------------------------------------
70     // Event handlers & initialization
71
72     /**
73      * Must be called after initializeGraph.
74      */
75     private void initializeInput() {
76         // Get the main input from the view's secondary ID.
77         String secondaryId = getViewSite().getSecondaryId();
78         if (secondaryId == null)
79             // No input given!
80             return;
81
82         mainInput = ResourceInput.unmarshall(secondaryId);
83         try {
84             inputResource = mainInput.toResource(getSession());
85         } catch (DatabaseException e) {
86             ErrorLogger.defaultLogError(e);
87         }
88     }
89
90
91     /**
92      * Initializes graph data access and view resource ID input structures.
93      * 
94      * <p>
95      * This method is automatically called by
96      * {@link #createPartControl(Composite)}. Override to perform own
97      * graph-related initializations but be absolutely sure to call super the
98      * first thing. Clients must not directly call this method.
99      * </p>
100      */
101     @Override
102     protected void initialize() {
103         super.initialize();
104         initializeInput();
105     }
106
107     /**
108      * @return <code>true</code> if the input resource still exists, i.e.
109      *         there are triples with the subject of the input resource.
110      */
111     protected boolean inputExists(ReadGraph g) throws DatabaseException {
112         if (inputResource == null)
113             return false;
114         return g.hasStatement(inputResource);
115     }
116
117     @Override
118     protected void cleanup() {
119         inputResource = null;
120         super.cleanup();
121     }
122
123
124     /**
125      * @return the main input structure of this view which identifies a single
126      *         input resource
127      */
128     public ResourceInput getMainInput() {
129         return mainInput;
130     }
131
132
133     //----------------------------------------------------------------------
134     // Override these if necessary:
135
136     @Override
137     protected String getTitleText() {
138         return getInputName();
139     }
140
141     @Override
142     protected String getTitleTooltip() {
143         return getInputName();
144     }
145
146
147     /**
148      * Extends {@link #update(GraphChangeEvent)} to handle disappearing inputs
149      * by hiding the view.
150      * 
151      * @param event
152      *            the received change event
153      */
154     @Override
155     protected void update(ChangeEvent event) throws DatabaseException {
156         ReadGraph g = event.getGraph();
157
158         // If the input no longer exists, the editor should be closed since the
159         // situation is analogous to having an IEditorPart input, such as a
160         // file, deleted suddenly.
161         if (!inputExists(g)) {
162             WorkbenchUtils.hideView(getViewSite().getWorkbenchWindow(), this);
163             return;
164         }
165
166         updateModelCache(g);
167         reload(g);
168     }
169
170     private void updateModelCache(ReadGraph graph) {
171         try {
172                 Layer0 L0 = Layer0.getInstance(graph);
173             inputName = graph.getPossibleRelatedValue(inputResource, L0.HasName);
174             if (inputName == null)
175                 inputName = NO_NAME;
176         } catch (DatabaseException e) {
177             inputName = MULTIPLE_NAMES;
178         }
179     }
180
181 }