KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > resources > CharsetDeltaJob


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.resources;
12
13 import org.eclipse.core.internal.utils.*;
14 import org.eclipse.core.internal.watson.*;
15 import org.eclipse.core.resources.*;
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.core.runtime.content.IContentTypeManager;
18 import org.eclipse.core.runtime.content.IContentTypeManager.ContentTypeChangeEvent;
19 import org.eclipse.core.runtime.jobs.Job;
20 import org.osgi.framework.Bundle;
21
22 /**
23  * Detects changes to content types/project preferences and
24  * broadcasts any corresponding encoding changes as resource deltas.
25  */

26
27 public class CharsetDeltaJob extends Job implements IContentTypeManager.IContentTypeChangeListener {
28
29     // this is copied in the runtime tests - if changed here, has to be changed there too
30
public final static String JavaDoc FAMILY_CHARSET_DELTA = ResourcesPlugin.PI_RESOURCES + "charsetJobFamily"; //$NON-NLS-1$
31

32     interface ICharsetListenerFilter {
33
34         /**
35          * Returns the path for the node in the tree we are interested in.
36          */

37         IPath getRoot();
38
39         /**
40          * Returns whether the corresponding resource is affected by this change.
41          */

42         boolean isAffected(ResourceInfo info, IPathRequestor requestor);
43     }
44
45     private ThreadLocal JavaDoc disabled = new ThreadLocal JavaDoc();
46
47     private final Bundle systemBundle = Platform.getBundle("org.eclipse.osgi"); //$NON-NLS-1$
48
private Queue work = new Queue();
49
50     Workspace workspace;
51
52     private static final int CHARSET_DELTA_DELAY = 500;
53
54     public CharsetDeltaJob(Workspace workspace) {
55         super(Messages.resources_charsetBroadcasting);
56         this.workspace = workspace;
57     }
58
59     private void addToQueue(ICharsetListenerFilter filter) {
60         synchronized (work) {
61             work.add(filter);
62         }
63         schedule(CHARSET_DELTA_DELAY);
64     }
65
66     public boolean belongsTo(Object JavaDoc family) {
67         return FAMILY_CHARSET_DELTA.equals(family);
68     }
69
70     public void charsetPreferencesChanged(final IProject project) {
71         // avoid reacting to changes made by ourselves
72
if (isDisabled())
73             return;
74         // ensure all resources under the affected project are
75
// reported as having encoding changes
76
ICharsetListenerFilter filter = new ICharsetListenerFilter() {
77
78             public IPath getRoot() {
79                 // visit the project subtree
80
return project.getFullPath();
81             }
82
83             public boolean isAffected(ResourceInfo info, IPathRequestor requestor) {
84                 // for now, mark all resources in the project as potential encoding resource changes
85
return true;
86             }
87         };
88         addToQueue(filter);
89     }
90
91     public void contentTypeChanged(final ContentTypeChangeEvent event) {
92         // check all files that may be affected by this change (taking
93
// only the current content type state into account
94
// dispatch a job to generate the deltas
95
ICharsetListenerFilter filter = new ICharsetListenerFilter() {
96
97             public IPath getRoot() {
98                 // visit all resources in the workspace
99
return Path.ROOT;
100             }
101
102             public boolean isAffected(ResourceInfo info, IPathRequestor requestor) {
103                 if (info.getType() != IResource.FILE)
104                     return false;
105                 return event.getContentType().isAssociatedWith(requestor.requestName());
106             }
107         };
108         addToQueue(filter);
109     }
110
111     private boolean isDisabled() {
112         return disabled.get() != null;
113     }
114
115     private void processNextEvent(final ICharsetListenerFilter filter, IProgressMonitor monitor) throws CoreException {
116         IElementContentVisitor visitor = new IElementContentVisitor() {
117             public boolean visitElement(ElementTree tree, IPathRequestor requestor, Object JavaDoc elementContents) {
118                 ResourceInfo info = (ResourceInfo) elementContents;
119                 if (!filter.isAffected(info, requestor))
120                     return true;
121                 info = workspace.getResourceInfo(requestor.requestPath(), false, true);
122                 if (info == null)
123                     return false;
124                 info.incrementCharsetGenerationCount();
125                 return true;
126             }
127         };
128         try {
129             new ElementTreeIterator(workspace.getElementTree(), filter.getRoot()).iterate(visitor);
130         } catch (WrappedRuntimeException e) {
131             throw (CoreException) e.getTargetException();
132         }
133         if (monitor.isCanceled())
134             throw new OperationCanceledException();
135     }
136
137     private ICharsetListenerFilter removeFromQueue() {
138         synchronized (work) {
139             return (ICharsetListenerFilter) work.remove();
140         }
141     }
142
143     /* (non-Javadoc)
144      * @see org.eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor)
145      */

146     public IStatus run(IProgressMonitor monitor) {
147         monitor = Policy.monitorFor(monitor);
148         try {
149             String JavaDoc message = Messages.resources_charsetBroadcasting;
150             monitor.beginTask(message, Policy.totalWork);
151             try {
152                 workspace.prepareOperation(null, monitor);
153                 workspace.beginOperation(true);
154                 ICharsetListenerFilter next;
155                 //if the system is shutting down, don't broadcast
156
while (systemBundle.getState() != Bundle.STOPPING && (next = removeFromQueue()) != null)
157                     processNextEvent(next, monitor);
158             } catch (OperationCanceledException e) {
159                 workspace.getWorkManager().operationCanceled();
160                 return Status.CANCEL_STATUS;
161             } finally {
162                 workspace.endOperation(null, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
163             }
164             monitor.worked(Policy.opWork);
165         } catch (CoreException sig) {
166             return sig.getStatus();
167         } finally {
168             monitor.done();
169         }
170         return Status.OK_STATUS;
171     }
172
173     /**
174      * Turns off reaction to changes in the preference file.
175      */

176     public void setDisabled(boolean disabled) {
177         // using a thread local because this can be called by multiple threads concurrently
178
this.disabled.set(disabled ? Boolean.TRUE : null);
179     }
180
181     public void shutdown() {
182         Platform.getContentTypeManager().removeContentTypeChangeListener(this);
183     }
184
185     public void startup() {
186         Platform.getContentTypeManager().addContentTypeChangeListener(this);
187     }
188 }
189
Popular Tags