001: /*******************************************************************************
002: * Copyright (c) 2006 IBM Corporation.
003: * Licensed Material - Property of IBM. All rights reserved.
004: * US Government Users Restricted Rights - Use, duplication or disclosure
005: * restricted by GSA ADP Schedule Contract with IBM Corp.
006: *
007: * Contributors:
008: * IBM Corporation - initial API and implementation
009: *******************************************************************************/package org.eclipse.ui.examples.navigator;
010:
011: import java.io.IOException;
012: import java.util.ArrayList;
013: import java.util.Enumeration;
014: import java.util.HashMap;
015: import java.util.List;
016: import java.util.Map;
017: import java.util.Properties;
018:
019: import org.eclipse.core.resources.IFile;
020: import org.eclipse.core.resources.IResource;
021: import org.eclipse.core.resources.IResourceChangeEvent;
022: import org.eclipse.core.resources.IResourceChangeListener;
023: import org.eclipse.core.resources.IResourceDelta;
024: import org.eclipse.core.resources.IResourceDeltaVisitor;
025: import org.eclipse.core.resources.ResourcesPlugin;
026: import org.eclipse.core.runtime.CoreException;
027: import org.eclipse.core.runtime.IProgressMonitor;
028: import org.eclipse.core.runtime.IStatus;
029: import org.eclipse.core.runtime.Status;
030: import org.eclipse.jface.viewers.ITreeContentProvider;
031: import org.eclipse.jface.viewers.StructuredViewer;
032: import org.eclipse.jface.viewers.Viewer;
033: import org.eclipse.ui.progress.UIJob;
034:
035: /**
036: * Provides the properties contained in a *.properties file as children of that
037: * file in a Common Navigator.
038: * @since 3.2
039: */
040: public class PropertiesContentProvider implements ITreeContentProvider,
041: IResourceChangeListener, IResourceDeltaVisitor {
042:
043: private static final Object[] NO_CHILDREN = new Object[0];
044:
045: private static final Object PROPERTIES_EXT = "properties"; //$NON-NLS-1$
046:
047: private final Map/*<IFile, PropertiesTreeData[]>*/cachedModelMap = new HashMap();
048:
049: private StructuredViewer viewer;
050:
051: /**
052: * Create the PropertiesContentProvider instance.
053: *
054: * Adds the content provider as a resource change listener to track changes on disk.
055: *
056: */
057: public PropertiesContentProvider() {
058: ResourcesPlugin.getWorkspace().addResourceChangeListener(this ,
059: IResourceChangeEvent.POST_CHANGE);
060: }
061:
062: /**
063: * Return the model elements for a *.properties IFile or
064: * NO_CHILDREN for otherwise.
065: */
066: public Object[] getChildren(Object parentElement) {
067: Object[] children = null;
068: if (parentElement instanceof PropertiesTreeData) {
069: children = NO_CHILDREN;
070: } else if (parentElement instanceof IFile) {
071: /* possible model file */
072: IFile modelFile = (IFile) parentElement;
073: if (PROPERTIES_EXT.equals(modelFile.getFileExtension())) {
074: children = (PropertiesTreeData[]) cachedModelMap
075: .get(modelFile);
076: if (children == null && updateModel(modelFile) != null) {
077: children = (PropertiesTreeData[]) cachedModelMap
078: .get(modelFile);
079: }
080: }
081: }
082: return children != null ? children : NO_CHILDREN;
083: }
084:
085: /**
086: * Load the model from the given file, if possible.
087: * @param modelFile The IFile which contains the persisted model
088: */
089: private synchronized Properties updateModel(IFile modelFile) {
090:
091: if (PROPERTIES_EXT.equals(modelFile.getFileExtension())) {
092: Properties model = new Properties();
093: if (modelFile.exists()) {
094: try {
095: model.load(modelFile.getContents());
096:
097: String propertyName;
098: List properties = new ArrayList();
099: for (Enumeration names = model.propertyNames(); names
100: .hasMoreElements();) {
101: propertyName = (String) names.nextElement();
102: properties.add(new PropertiesTreeData(
103: propertyName, model
104: .getProperty(propertyName),
105: modelFile));
106: }
107: PropertiesTreeData[] propertiesTreeData = (PropertiesTreeData[]) properties
108: .toArray(new PropertiesTreeData[properties
109: .size()]);
110:
111: cachedModelMap.put(modelFile, propertiesTreeData);
112: return model;
113: } catch (IOException e) {
114: } catch (CoreException e) {
115: }
116: } else {
117: cachedModelMap.remove(modelFile);
118: }
119: }
120: return null;
121: }
122:
123: public Object getParent(Object element) {
124: if (element instanceof PropertiesTreeData) {
125: PropertiesTreeData data = (PropertiesTreeData) element;
126: return data.getFile();
127: }
128: return null;
129: }
130:
131: public boolean hasChildren(Object element) {
132: if (element instanceof PropertiesTreeData) {
133: return false;
134: } else if (element instanceof IFile) {
135: return PROPERTIES_EXT.equals(((IFile) element)
136: .getFileExtension());
137: }
138: return false;
139: }
140:
141: public Object[] getElements(Object inputElement) {
142: return getChildren(inputElement);
143: }
144:
145: public void dispose() {
146: cachedModelMap.clear();
147: ResourcesPlugin.getWorkspace().removeResourceChangeListener(
148: this );
149: }
150:
151: public void inputChanged(Viewer aViewer, Object oldInput,
152: Object newInput) {
153: if (oldInput != null && !oldInput.equals(newInput))
154: cachedModelMap.clear();
155: viewer = (StructuredViewer) aViewer;
156: }
157:
158: /*
159: * (non-Javadoc)
160: *
161: * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
162: */
163: public void resourceChanged(IResourceChangeEvent event) {
164:
165: IResourceDelta delta = event.getDelta();
166: try {
167: delta.accept(this );
168: } catch (CoreException e) {
169: e.printStackTrace();
170: }
171: }
172:
173: /*
174: * (non-Javadoc)
175: *
176: * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
177: */
178: public boolean visit(IResourceDelta delta) {
179:
180: IResource source = delta.getResource();
181: switch (source.getType()) {
182: case IResource.ROOT:
183: case IResource.PROJECT:
184: case IResource.FOLDER:
185: return true;
186: case IResource.FILE:
187: final IFile file = (IFile) source;
188: if (PROPERTIES_EXT.equals(file.getFileExtension())) {
189: updateModel(file);
190: new UIJob("Update Properties Model in CommonViewer") { //$NON-NLS-1$
191: public IStatus runInUIThread(
192: IProgressMonitor monitor) {
193: if (viewer != null
194: && !viewer.getControl().isDisposed())
195: viewer.refresh(file);
196: return Status.OK_STATUS;
197: }
198: }.schedule();
199: }
200: return false;
201: }
202: return false;
203: }
204: }
|