-
Notifications
You must be signed in to change notification settings - Fork 1
/
Startup.java
154 lines (143 loc) · 5.46 KB
/
Startup.java
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
/*
* Eclipse Minify Builder
* Copyright (C) 2017 Michael N. Lipp
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
package org.jdrupes.eclipse.minify.plugin;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.ui.IStartup;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* Started immediately with the workbench, this class registers a ResourceChangeListener
* that adapts the project scoped properties of a file to moves (renames) and deletions.
*
* The mechanism provided here stores file related properties in a project
* scoped preferences node. The key for accessing properties is generated by
* appending the property name, two slashes as separator and the project
* relative, os independent path (see {@link #preferenceKey(IResource, String)}).
* This allows all properties of a file to be identified using
* {@link String#endsWith(String)}. This is similar to the scheme used by
* {@code org.eclipse.core.resources.prefs} for storing e.g. the encoding of a file
* in project scoped preferences.
*
* Such a class (started with the workbench) should -- according to the Eclipse
* documentation -- never be written.
*/
public class Startup implements IStartup {
/**
* Returns the plugin's project scoped preferences using the given
* resource to identify the project.
*
* @param resource a resource from the project
* @return the preferences
*/
public static Preferences preferences(IResource resource) {
ProjectScope projectScope = new ProjectScope(resource.getProject());
return projectScope.getNode(MinifyBuilder.BUILDER_ID);
}
/**
* Generate the key for a given resource and its associated property.
*
* @param resource the resource
* @param property the property
* @return the key
*/
public static String preferenceKey(IResource resource, String property) {
return property + "//" + resource.getProjectRelativePath().toPortableString();
}
/**
* Remove a resource (i.e. all its properties) from the builder's preferences.
*
* @param prefs the preferences
* @param resource the resource
* @throws BackingStoreException
*/
public static void removeResource(Preferences prefs, IResource resource)
throws BackingStoreException {
String[] keys = prefs.keys();
for (String key: keys) {
if (key.endsWith("//" + resource.getProjectRelativePath().toPortableString())) {
prefs.remove(key);
}
}
prefs.flush();
}
/**
* Associate one resource's properties with another resource.
*
* @param fromPrefs the preferences to take the properties from
* @param fromResource the resource to take the properties from
* @param toPrefs the preferences to move the properties to
* @param toResource the resource to associated with the properties
* @throws BackingStoreException
*/
public static void moveResource(Preferences fromPrefs, IResource fromResource,
Preferences toPrefs, IResource toResource)
throws BackingStoreException {
String[] keys = fromPrefs.keys();
for (String key: keys) {
if (key.endsWith("//" + fromResource.getProjectRelativePath().toPortableString())) {
String resourcePreference = key.substring(0, key.indexOf('/'));
toPrefs.put(preferenceKey(toResource, resourcePreference), fromPrefs.get(key, ""));
fromPrefs.remove(key);
}
}
fromPrefs.flush();
toPrefs.flush();
}
@Override
public void earlyStartup() {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.addResourceChangeListener(new IResourceChangeListener() {
@Override
public void resourceChanged(IResourceChangeEvent event) {
try {
handleDelta(event.getDelta());
} catch (BackingStoreException e) {
e.printStackTrace();
}
}
}, IResourceChangeEvent.PRE_BUILD);
}
private void handleDelta(IResourceDelta delta) throws BackingStoreException {
if (delta.getAffectedChildren().length == 0) {
if ((delta.getKind() & IResourceDelta.REMOVED) != 0) {
IResource resource = delta.getResource();
Preferences resPrefs = Startup.preferences(resource);
if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
IPath toPath = delta.getMovedToPath();
IResource toResource = ResourcesPlugin
.getWorkspace().getRoot().findMember(toPath);
Startup.moveResource(resPrefs, resource,
Startup.preferences(toResource), toResource);
}
Startup.removeResource(resPrefs, resource);
}
return;
}
for (IResourceDelta child : delta.getAffectedChildren(
IResourceDelta.CHANGED | IResourceDelta.REMOVED)) {
handleDelta(child);
}
}
}