Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: e9e4e56ec286239b5798a389433131a753896e9d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*******************************************************************************
 * Copyright (c) 2011 Wind River Systems, Inc. and others. 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:
 * Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tcf.te.ui.trees;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.tcf.te.ui.activator.UIPlugin;
import org.eclipse.tcf.te.ui.interfaces.IViewerInput;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.XMLMemento;

/**
 * The tree viewer state manager used to provide the following states:
 * 1. The viewers' state persistence.
 * 2. Access the viewers' state.
 */
public class ViewerStateManager {
	// The single instance to provide the management.
	private static ViewerStateManager instance;

	/**
	 * Get the single instance of the manager.
	 * 
	 * @return The single instance of the viewer state manager.
	 */
	public static ViewerStateManager getInstance() {
		if (instance == null) {
			instance = new ViewerStateManager();
		}
		return instance;
	}

	// The map to store the viewers' states.
	private Map<String, TreeViewerState> viewerStates;

	/**
	 * Get the viewer state for the specified input id.
	 * 
	 * @param inputId
	 * @return
	 */
	public TreeViewerState getViewerState(String inputId) {
		return viewerStates.get(inputId);
	}

	/**
	 * Get the filter descriptor for the specified viewer and input.
	 * 
	 * @param viewerId The viewer's id.
	 * @param input The input.
	 * @return The enabled filter descriptors.
	 */
	public FilterDescriptor[] getFilterDescriptors(String viewerId, Object input) {
		if (input != null) {
			TreeViewerExtension viewerExtension = new TreeViewerExtension(viewerId);
			FilterDescriptor[] filterDescriptors = viewerExtension.parseFilters(input);
			if (filterDescriptors != null) {
				IViewerInput viewerInput = getViewerInput(input);
				if(viewerInput != null) {
					String inputId =viewerInput.getInputId();
					inputId = viewerId + "." + inputId; //$NON-NLS-1$
					TreeViewerState viewerState = getViewerState(inputId);
					if (viewerState != null) {
						viewerState.updateFilterDescriptor(filterDescriptors);
					}
				}
				return filterDescriptors;
			}
		}
		return null;
	}
	
	/***
	 * Get the viewer input from the input of the tree viewer.
	 * If the input is an instance of IViewerInput, then return
	 * the input. If the input can be adapted to a IViewerInput,
	 * then return the adapted object.
	 * 
	 * @param input The input of the tree viewer.
	 * @return A viewer input or null.
	 */
	static IViewerInput getViewerInput(Object input) {
		IViewerInput viewerInput = null;
		if (input != null) {
			if (input instanceof IViewerInput) {
				viewerInput = (IViewerInput) input;
			}
			else {
				if (input instanceof IAdaptable) {
					viewerInput = (IViewerInput) ((IAdaptable) input).getAdapter(IViewerInput.class);
				}
				if (viewerInput == null) {
					viewerInput = (IViewerInput) Platform.getAdapterManager().getAdapter(input, IViewerInput.class);
				}
			}
		}
		return viewerInput;
    }
	
	/**
	 * Put the viewer state with its input id into the map.
	 * 
	 * @param inputId The id of the input.
	 * @param viewerState The viewer's state.
	 */
	public void putViewerState(String inputId, TreeViewerState viewerState) {
		viewerStates.put(inputId, viewerState);
	}

	/**
	 * Load all the viewer states from an external storage. Called by the plugin's
	 * activator before they are used to configure the tree viewers.
	 */
	public void loadViewerStates() {
		viewerStates = Collections.synchronizedMap(new HashMap<String, TreeViewerState>());
		final File stateFile = getViewerStateFile();
		if (stateFile.exists()) {
			SafeRunner.run(new SafeRunnable() {
				@Override
                public void handleException(Throwable e) {
					// Ignore exception
                }
				@Override
				public void run() throws Exception {
					Reader reader = null;
					try {
						reader = new BufferedReader(new InputStreamReader(new FileInputStream(stateFile), "UTF-8")); //$NON-NLS-1$
						XMLMemento root = XMLMemento.createReadRoot(reader);
						loadViewerState(root);
					}
					finally {
						if (reader != null) {
							try {
								reader.close();
							}
							catch (IOException e) {
							}
						}
					}
				}
			});
		}
	}

	/**
	 * Load the viewer states from the memento root.
	 * 
	 * @param root The memento's root.
	 */
	void loadViewerState(IMemento root) {
		IMemento[] children = root.getChildren("viewerState"); //$NON-NLS-1$
		if (children != null && children.length > 0) {
			for (IMemento child : children) {
				createViewerState(child);
			}
		}
	}

	/**
	 * Create a viewer state instance using the specified memento element.
	 * 
	 * @param mViewerState The memento element.
	 */
	void createViewerState(IMemento mViewerState) {
		String id = mViewerState.getString("id"); //$NON-NLS-1$
		Assert.isNotNull(id);
		TreeViewerState viewerState = new TreeViewerState();
		viewerState.restoreState(mViewerState);
		viewerStates.put(id, viewerState);
	}

	/**
	 * Get the viewer state files. The default location is a file named "viewerstates.xml" 
	 * under the plugin's state cache. If it is not available, default it to the ".tcf" 
	 * directory under the user's home.
	 * 
	 * @return The viewer state file.
	 */
	private File getViewerStateFile() {
		File location;
		try {
			location = UIPlugin.getDefault().getStateLocation().toFile();
		}
		catch (IllegalStateException e) {
			// An RCP workspace-less environment (-data @none)
			location = new File(System.getProperty("user.home"), ".tcf"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		// Create the location if it not exist
		if (!location.exists()) location.mkdir();
		location = new File(location, "viewerstates.xml"); //$NON-NLS-1$
		return location;
	}

	/**
	 * Store the the viewer states. Called by the plugin's activator to
	 * save the state data.
	 */
	public void storeViewerStates() {
		final File stateFile = getViewerStateFile();
		final XMLMemento root = XMLMemento.createWriteRoot("viewerStates"); //$NON-NLS-1$
		storeViewerStates(root);
		SafeRunner.run(new SafeRunnable() {
			@Override
            public void handleException(Throwable e) {
				// Ignore exception
            }
			@Override
			public void run() throws Exception {
				Writer writer = null;
				try {
					writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(stateFile), "UTF-8")); //$NON-NLS-1$
					root.save(writer);
				}
				finally {
					if (writer != null) {
						try {
							writer.close();
						}
						catch (IOException e) {
						}
					}
				}
			}
		});
	}

	/**
	 * Store the viewer's state to a memento element.
	 * 
	 * @param root The memento element.
	 */
	void storeViewerStates(IMemento root) {
		for (String id : viewerStates.keySet()) {
			IMemento mViewerState = root.createChild("viewerState"); //$NON-NLS-1$
			mViewerState.putString("id", id); //$NON-NLS-1$
			TreeViewerState viewerState = viewerStates.get(id);
			viewerState.saveState(mViewerState);
		}
	}

	/**
	 * Create a viewer state instance using the column descriptors and the filter descriptors specified.
	 * 
	 * @param columns The column descriptors.
	 * @param filters The filter descriptors.
	 * @return The tree viewer state instance.
	 */
	public static TreeViewerState createViewerState(ColumnDescriptor[] columns, FilterDescriptor[] filters) {
		TreeViewerState viewerState = new TreeViewerState();
		if (columns != null) {
			for (ColumnDescriptor column : columns) {
				viewerState.addColumn(column);
			}
		}
		if (filters != null) {
			for(FilterDescriptor filter : filters) {
				viewerState.addFilter(filter);
			}
		}
		return viewerState;
	}
}

Back to the top