Revision 269

View differences:

org.gvsig.educa.portableview/trunk/org.gvsig.educa.portableview/org.gvsig.educa.portableview.lib/org.gvsig.educa.portableview.lib.impl/src/main/java/org/gvsig/educa/portableview/impl/util/PersistenceUtils.java
23 23

  
24 24
import java.io.File;
25 25
import java.net.MalformedURLException;
26
import java.net.URI;
26 27
import java.net.URISyntaxException;
27 28
import java.net.URL;
29
import java.text.MessageFormat;
28 30
import java.util.HashSet;
29 31
import java.util.Iterator;
30 32
import java.util.Map;
......
38 40

  
39 41
/**
40 42
 * Utilities for manage {@link PersistentState} objects
41
 * 
43
 *
42 44
 * @author gvSIG Team
43 45
 * @version $Id$
44
 * 
46
 *
45 47
 */
46 48
public abstract class PersistenceUtils {
47 49

  
48
    /**
49
     * Adjust all <i>file-system related</i> values with <code>rootFolder</code>
50
     * as root folder.
51
     * 
52
     * @param state
53
     * @param rootFolder
54
     * @throws PersistenceException
55
     */
56
    public static void fixMapContextFilePaths(PersistentState state,
57
        File rootFolder) throws PersistenceException {
58
        PersistentContext context = state.getContext();
50
	/**
51
	 * Adjust all <i>file-system related</i> values with <code>rootFolder</code>
52
	 * as root folder.
53
	 *
54
	 * @param state
55
	 * @param rootFolder
56
	 * @throws PersistenceException
57
	 */
58
	public static void fixMapContextFilePaths(PersistentState state,
59
			File rootFolder) throws PersistenceException {
60
		PersistentContext context = state.getContext();
59 61

  
60
        @SuppressWarnings("unchecked")
61
        Iterator<PersistentState> statesIterator = context.iterator();
62
        while (statesIterator.hasNext()) {
63
            PersistentState aState = statesIterator.next();
64
            DynStruct definition = aState.getDefinition();
65
            DynField[] fields = definition.getDynFields();
66
            for (DynField field : fields) {
67
                if ((field.getType() == org.gvsig.tools.dataTypes.DataTypes.FILE)
68
                    || (field.getType() == org.gvsig.tools.dataTypes.DataTypes.FOLDER)) {
69
                    File value = aState.getFile(field.getName());
70
                    value = fixRelativeFilePath(value, rootFolder);
71
                    aState.set(field.getName(), value);
72
                } else
73
                    if (field.getType() == org.gvsig.tools.dataTypes.DataTypes.URL) {
74
                        try {
75
                            URL value = aState.getURL(field.getName());
76
                            if ("FILE".equalsIgnoreCase(value.getProtocol())) {
77
                                File file = new File(value.getFile());
78
                                file = fixRelativeFilePath(file, rootFolder);
79
                                aState.set(field.getName(), file.toURI()
80
                                    .toURL());
81
                            }
82
                        } catch (PersistenceException e) {
83
                            // do nothing
84
                        } catch (MalformedURLException e) {
85
                            // do nothing
86
                        }
87
                    }
88
            }
89
        }
90
    }
62
		@SuppressWarnings("unchecked")
63
		Iterator<PersistentState> statesIterator = context.iterator();
64
		while (statesIterator.hasNext()) {
65
			PersistentState aState = statesIterator.next();
66
			DynStruct definition = aState.getDefinition();
67
			DynField[] fields = definition.getDynFields();
68
			for (DynField field : fields) {
69
				if ((field.getName() == "uri" && field.getType() == org.gvsig.tools.dataTypes.DataTypes.STRING)) {
70
					String value = aState.getString(field.getName());
71
					if (value.startsWith("file:")) {
72
						File file = aState.getFile(field.getName());
73
						file = fixRelativeFilePath(file, rootFolder);
74
						aState.set(field.getName(), file);
75
					}
76
				} else if ((field.getName() == "fileName" && field.getType() == org.gvsig.tools.dataTypes.DataTypes.URI)) {
77
					URI uri = aState.getURI(field.getName());
78
					if (uri.getHost() == null) {
79
						try {
80
							URI newURI = fixRelativePathURI(uri, rootFolder);
81
							aState.set(field.getName(), newURI);
82
						} catch (URISyntaxException e1) {
83
							e1.printStackTrace();
84
						}
85
					}
86
				}else if ((field.getType() == org.gvsig.tools.dataTypes.DataTypes.FILE)
87
						|| (field.getType() == org.gvsig.tools.dataTypes.DataTypes.FOLDER)) {
88
					File value = aState.getFile(field.getName());
89
					value = fixRelativeFilePath(value, rootFolder);
90
					aState.set(field.getName(), value);
91
				} else if (field.getType() == org.gvsig.tools.dataTypes.DataTypes.URL) {
92
					try {
93
						URL value = aState.getURL(field.getName());
94
						if ("FILE".equalsIgnoreCase(value.getProtocol())) {
95
							File file = new File(value.getFile());
96
							file = fixRelativeFilePath(file, rootFolder);
97
							aState.set(field.getName(), file.toURI().toURL());
98
						}
99
					} catch (PersistenceException e) {
100
						// do nothing
101
					} catch (MalformedURLException e) {
102
						// do nothing
103
					}
104
				}
105
			}
106
		}
107
	}
91 108

  
92
    /**
93
     * Fixes relative path to get an absolute one
94
     * 
95
     * @param file
96
     * @param rootFolder
97
     * @return
98
     */
99
    private static File fixRelativeFilePath(File file, File rootFolder) {
100
        if (file.isAbsolute()) {
101
            return file;
102
        }
103
        return new File(rootFolder, file.getPath()).getAbsoluteFile();
104
    }
109
	/**
110
	 * Fixes relative path of URI object to get an absolute one
111
	 *
112
	 * @param uri
113
	 * @param rootFolder
114
	 * @return
115
	 * @throws URISyntaxException
116
	 */
117
	private static URI fixRelativePathURI(URI uri, File rootFolder)
118
			throws URISyntaxException {
119
		String relativePath = uri.getPath();
120
		String fixedPath = relativePath.replace("/portable_view/",
121
				rootFolder.getAbsolutePath());
122
		return new URI(fixedPath);
123
	}
105 124

  
106
    /**
107
     * Returns a list of all <i>file-system related</i> <code>state</code>'s
108
     * values
109
     * 
110
     * @param state
111
     * @return
112
     * @throws PersistenceException
113
     */
114
    public static Set<File> getRelatedFiles(PersistentState state)
115
        throws PersistenceException {
116
        Set<File> relatedFiles = new HashSet<File>();
117
        PersistentContext context = state.getContext();
125
	/**
126
	 * Fixes relative path to get an absolute one
127
	 *
128
	 * @param file
129
	 * @param rootFolder
130
	 * @return
131
	 */
132
	private static File fixRelativeFilePath(File file, File rootFolder) {
133
		if (file.isAbsolute()) {
134
			return file;
135
		}
136
		return new File(rootFolder, file.getPath()).getAbsoluteFile();
137
	}
118 138

  
119
        @SuppressWarnings("unchecked")
120
        Iterator<PersistentState> statesIterator = context.iterator();
121
        while (statesIterator.hasNext()) {
122
            PersistentState aState = statesIterator.next();
123
            DynStruct definition = aState.getDefinition();
124
            DynField[] fields = definition.getDynFields();
125
            for (DynField field : fields) {
126
                if ((field.getType() == org.gvsig.tools.dataTypes.DataTypes.FILE)
127
                    || (field.getType() == org.gvsig.tools.dataTypes.DataTypes.FOLDER)) {
128
                    relatedFiles.add(aState.getFile(field.getName()));
129
                } else
130
                    if (field.getType() == org.gvsig.tools.dataTypes.DataTypes.URL) {
131
                        try {
132
                            URL value = aState.getURL(field.getName());
133
                            if ("FILE".equalsIgnoreCase(value.getProtocol())) {
134
                                relatedFiles.add(new File(value.getFile()));
135
                            }
136
                        } catch (PersistenceException e) {
137
                            // do nothing
138
                        }
139
                    }
140
            }
141
        }
142
        return relatedFiles;
143
    }
139
	/**
140
	 * Returns a list of all <i>file-system related</i> <code>state</code>'s
141
	 * values
142
	 *
143
	 * @param state
144
	 * @return
145
	 * @throws PersistenceException
146
	 */
147
	public static Set<File> getRelatedFiles(PersistentState state)
148
			throws PersistenceException {
149
		Set<File> relatedFiles = new HashSet<File>();
150
		PersistentContext context = state.getContext();
144 151

  
145
    /**
146
     * <p>
147
     * Adjust all Files in <code>state</code> based on
148
     * <code>transformMapping</code>.
149
     * </p>
150
     * <p>
151
     * Also, optionally. make final file path relatives to
152
     * <code>rootFolder</code> if it's provided. (only in file which
153
     * <code>rootFolder</code> is ancestor of)
154
     * </p>
155
     * <p>
156
     * All filenames will use unix-like filesystem separator character
157
     * </p>
158
     * 
159
     * @param state
160
     *            to adjust
161
     * @param transformMapping
162
     *            mapping with source files as key and target as value
163
     * @param rootFolder
164
     *            base folder for relative paths (could be <code>null</code>)
165
     * @return set of <code>state</code> files with no matching in
166
     *         <code>transformMapping</code>
167
     * @throws PersistenceException
168
     */
169
    public static Set<File> relocateFiles(PersistentState state,
170
        Map<File, File> transformMapping, File rootFolder)
171
        throws PersistenceException {
172
        Set<File> missingFilesInMapping = new HashSet<File>();
173
        PersistentContext context = state.getContext();
174
        @SuppressWarnings("unchecked")
175
        Iterator<PersistentState> statesIterator = context.iterator();
176
        while (statesIterator.hasNext()) {
177
            PersistentState aState = statesIterator.next();
178
            DynStruct definition = aState.getDefinition();
179
            DynField[] fields = definition.getDynFields();
180
            for (DynField field : fields) {
181
                if ((field.getType() == org.gvsig.tools.dataTypes.DataTypes.FILE)
182
                    || (field.getType() == org.gvsig.tools.dataTypes.DataTypes.FOLDER)) {
183
                    File value = aState.getFile(field.getName());
184
                    value =
185
                        getTransformedFile(value, transformMapping,
186
                            missingFilesInMapping, rootFolder);
187
                    aState.set(field.getName(), value);
188
                } else
189
                    if (field.getType() == org.gvsig.tools.dataTypes.DataTypes.URL) {
190
                        try {
191
                            URL value = aState.getURL(field.getName());
192
                            if ("FILE".equalsIgnoreCase(value.getProtocol())) {
193
                                File file = new File(value.toURI());
194
                                file =
195
                                    getTransformedFile(file, transformMapping,
196
                                        missingFilesInMapping, rootFolder);
197
                                String filename = file.toString();
198
                                if (!FileUtils.UNIXLIKE_FILESYSTEM) {
199
                                    filename =
200
                                        FilenameUtils
201
                                            .separatorsToUnix(filename);
202
                                }
203
                                value = new URL("file", "", filename);
204
                                aState.set(field.getName(), value);
205
                            }
206
                        } catch (MalformedURLException e) {
207
                            // do nothind
208
                        } catch (URISyntaxException e) {
209
                            // do nothind
210
                        }
211
                    }
212
            }
213
        }
214
        return missingFilesInMapping;
215
    }
152
		@SuppressWarnings("unchecked")
153
		Iterator<PersistentState> statesIterator = context.iterator();
154
		while (statesIterator.hasNext()) {
155
			PersistentState aState = statesIterator.next();
156
			DynStruct definition = aState.getDefinition();
157
			DynField[] fields = definition.getDynFields();
158
			for (DynField field : fields) {
159
				if (field.getName() == "uri"
160
						&& field.getType() == org.gvsig.tools.dataTypes.DataTypes.STRING) {
161
					String value = aState.getString(field.getName());
162
					// if value starts with / add file.
163
					if (value.startsWith("/")) {
164
						relatedFiles.add(new File(value));
165
					}
166
				} else if ((field.getType() == org.gvsig.tools.dataTypes.DataTypes.FILE)
167
						|| (field.getType() == org.gvsig.tools.dataTypes.DataTypes.FOLDER)) {
168
					relatedFiles.add(aState.getFile(field.getName()));
169
				} else if (field.getType() == org.gvsig.tools.dataTypes.DataTypes.URL) {
170
					try {
171
						URL value = aState.getURL(field.getName());
172
						if ("FILE".equalsIgnoreCase(value.getProtocol())) {
173
							relatedFiles.add(new File(value.getFile()));
174
						}
175
					} catch (PersistenceException e) {
176
						// do nothing
177
					}
178
				}
179
			}
180
		}
181
		return relatedFiles;
182
	}
216 183

  
217
    /**
218
     * <p>
219
     * Gets final file look up in <code>transformMapping</code>
220
     * </p>
221
     * <p>
222
     * If <code>source</code> not found in <code>transformMapping</code> adds it
223
     * to <code>missing</code> and uses <code>source</code> as return.
224
     * </p>
225
     * <p>
226
     * if <code>rootBaseFolder</code> is provided, makes returned file relative
227
     * to it (if <code>rootBaseFolder</code> is ancestor of returned file)
228
     * </p>
229
     * 
230
     * @param source
231
     * @param transformMapping
232
     * @param missing
233
     * @param rootBaseFolder
234
     * @return
235
     */
236
    private static File getTransformedFile(File source,
237
        Map<File, File> transformMapping, Set<File> missing, File rootBaseFolder) {
238
        File newFile = transformMapping.get(source);
239
        if (newFile == null) {
240
            missing.add(source);
241
            newFile = source;
242
        }
243
        if (rootBaseFolder != null) {
244
            newFile = FileUtils.getRelativeTo(newFile, rootBaseFolder);
245
        }
246
        return newFile;
247
    }
184
	/**
185
	 * <p>
186
	 * Adjust all Files in <code>state</code> based on
187
	 * <code>transformMapping</code>.
188
	 * </p>
189
	 * <p>
190
	 * Also, optionally. make final file path relatives to
191
	 * <code>rootFolder</code> if it's provided. (only in file which
192
	 * <code>rootFolder</code> is ancestor of)
193
	 * </p>
194
	 * <p>
195
	 * All filenames will use unix-like filesystem separator character
196
	 * </p>
197
	 *
198
	 * @param state
199
	 *            to adjust
200
	 * @param transformMapping
201
	 *            mapping with source files as key and target as value
202
	 * @param rootFolder
203
	 *            base folder for relative paths (could be <code>null</code>)
204
	 * @return set of <code>state</code> files with no matching in
205
	 *         <code>transformMapping</code>
206
	 * @throws PersistenceException
207
	 */
208
	public static Set<File> relocateFiles(PersistentState state,
209
			Map<File, File> transformMapping, File rootFolder)
210
			throws PersistenceException {
211
		Set<File> missingFilesInMapping = new HashSet<File>();
212
		PersistentContext context = state.getContext();
213
		@SuppressWarnings("unchecked")
214
		Iterator<PersistentState> statesIterator = context.iterator();
215
		while (statesIterator.hasNext()) {
216
			PersistentState aState = statesIterator.next();
217
			DynStruct definition = aState.getDefinition();
218
			DynField[] fields = definition.getDynFields();
219
			for (DynField field : fields) {
220
				if ((field.getName() == "uri" && field.getType() == org.gvsig.tools.dataTypes.DataTypes.STRING)) {
221
					String value = aState.getString(field.getName());
222
					if (value.startsWith("file:")) {
223
						File file = new File(value);
224
						file = getTransformedFile(file, transformMapping,
225
								missingFilesInMapping, rootFolder);
226
						aState.set(field.getName(), file);
227
					}
228
				} else if ((field.getName() == "fileName" && field.getType() == org.gvsig.tools.dataTypes.DataTypes.URI)) {
229
					URI uri = aState.getURI(field.getName());
230
					if (uri.getHost() == null) {
231
						File file = new File(uri.getPath());
232
						file = getTransformedFile(file, transformMapping,
233
								missingFilesInMapping, rootFolder);
234
						try {
235
							URI newURI = new URI("file", null,
236
									"/portable_view/" + file.getPath(), null);
237
							aState.set(field.getName(), newURI);
238
						} catch (URISyntaxException e) {
239
							e.printStackTrace();
240
						}
241
					}
242
				} else if ((field.getType() == org.gvsig.tools.dataTypes.DataTypes.FILE)
243
						|| (field.getType() == org.gvsig.tools.dataTypes.DataTypes.FOLDER)) {
244
					File value = aState.getFile(field.getName());
245
					value = getTransformedFile(value, transformMapping,
246
							missingFilesInMapping, rootFolder);
247
					aState.set(field.getName(), value);
248
				} else if (field.getType() == org.gvsig.tools.dataTypes.DataTypes.URL) {
249
					try {
250
						URL value = aState.getURL(field.getName());
251
						if ("FILE".equalsIgnoreCase(value.getProtocol())) {
252
							File file = new File(value.toURI());
253
							file = getTransformedFile(file, transformMapping,
254
									missingFilesInMapping, rootFolder);
255
							String filename = file.toString();
256
							if (!FileUtils.UNIXLIKE_FILESYSTEM) {
257
								filename = FilenameUtils
258
										.separatorsToUnix(filename);
259
							}
260
							value = new URL("file", "", filename);
261
							aState.set(field.getName(), value);
262
						}
263
					} catch (MalformedURLException e) {
264
						// do nothind
265
					} catch (URISyntaxException e) {
266
						// do nothind
267
					}
268
				}
269
			}
270
		}
271
		return missingFilesInMapping;
272
	}
248 273

  
274
	/**
275
	 * <p>
276
	 * Gets final file look up in <code>transformMapping</code>
277
	 * </p>
278
	 * <p>
279
	 * If <code>source</code> not found in <code>transformMapping</code> adds it
280
	 * to <code>missing</code> and uses <code>source</code> as return.
281
	 * </p>
282
	 * <p>
283
	 * if <code>rootBaseFolder</code> is provided, makes returned file relative
284
	 * to it (if <code>rootBaseFolder</code> is ancestor of returned file)
285
	 * </p>
286
	 *
287
	 * @param source
288
	 * @param transformMapping
289
	 * @param missing
290
	 * @param rootBaseFolder
291
	 * @return
292
	 */
293
	private static File getTransformedFile(File source,
294
			Map<File, File> transformMapping, Set<File> missing,
295
			File rootBaseFolder) {
296
		File newFile = transformMapping.get(source);
297
		if (newFile == null) {
298
			missing.add(source);
299
			newFile = source;
300
		}
301
		if (rootBaseFolder != null) {
302
			newFile = FileUtils.getRelativeTo(newFile, rootBaseFolder);
303
		}
304
		return newFile;
305
	}
306

  
249 307
}
org.gvsig.educa.portableview/trunk/org.gvsig.educa.portableview/org.gvsig.educa.portableview.lib/org.gvsig.educa.portableview.lib.impl/src/main/java/org/gvsig/educa/portableview/impl/MapResoucesManager.java
34 34
import java.util.SortedSet;
35 35
import java.util.TreeSet;
36 36

  
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39 37
import org.gvsig.educa.portableview.PortableViewLocator;
40 38
import org.gvsig.educa.portableview.impl.map.DefaultPortableView;
41 39
import org.gvsig.educa.portableview.impl.map.PortableViewLoader;
......
47 45
import org.gvsig.fmap.mapcontext.MapContext;
48 46
import org.gvsig.tools.ToolsLocator;
49 47
import org.gvsig.tools.dispose.Disposable;
48
import org.slf4j.Logger;
49
import org.slf4j.LoggerFactory;
50 50

  
51 51
/**
52 52
 * <p>
......
68 68
 */
69 69
public class MapResoucesManager implements Disposable {
70 70

  
71
    public static final int MAX_RESOUCES = 50;
71
	public static final int MAX_RESOUCES = 50;
72 72

  
73
    @SuppressWarnings("unused")
74
    private static final Logger LOG = LoggerFactory
75
        .getLogger(MapResoucesManager.class);
73
	@SuppressWarnings("unused")
74
	private static final Logger LOG = LoggerFactory
75
			.getLogger(MapResoucesManager.class);
76 76

  
77
    // Resources pool
78
    private final Map<File, MapResource> resources;
77
	// Resources pool
78
	private final Map<File, MapResource> resources;
79 79

  
80
    // MapLoader utility instance
81
    private PortableViewLoader mapLoader;
80
	// MapLoader utility instance
81
	private PortableViewLoader mapLoader;
82 82

  
83
    public MapResoucesManager(PortableViewLoader mapLoader) {
84
        // Create resource pool
85
        resources =
86
            new HashMap<File, MapResoucesManager.MapResource>(MAX_RESOUCES);
87
        // register this instance to be disposed on exit
88
        ToolsLocator.getDisposableManager().bind(this);
83
	public MapResoucesManager(PortableViewLoader mapLoader) {
84
		// Create resource pool
85
		resources = new HashMap<File, MapResoucesManager.MapResource>(
86
				MAX_RESOUCES);
87
		// register this instance to be disposed on exit
88
		ToolsLocator.getDisposableManager().bind(this);
89 89

  
90
        this.mapLoader = mapLoader;
91
    }
90
		this.mapLoader = mapLoader;
91
	}
92 92

  
93
    /**
94
     * <p>
95
     * Clean a resource
96
     * </p>
97
     * <p>
98
     * This performs:
99
     * <ul>
100
     * <li>dispose mapContext (if any)</li>
101
     * <li>clean deploy folder (if any). If it can be cleaned, schedules this
102
     * for application exit</li>
103
     * </ul>
104
     * </p>
105
     *
106
     * @param resource
107
     */
108
    private void cleanResource(MapResource resource) {
109
        if ((resource.deployFolder != null) && resource.deployFolder.exists()) {
110
            if (resource.mapContext != null) {
111
                resource.mapContext.dispose();
112
                resource.mapContext = null;
113
            }
114
            try {
115
                FileUtils.forceDelete(resource.deployFolder);
116
            } catch (IOException e) {
117
                try {
118
                    FileUtils.forceDeleteOnExit(resource.deployFolder);
119
                } catch (IOException e1) {
120
                    // Do nothing
121
                }
122
                resource.deployFolder = null;
93
	/**
94
	 * <p>
95
	 * Clean a resource
96
	 * </p>
97
	 * <p>
98
	 * This performs:
99
	 * <ul>
100
	 * <li>dispose mapContext (if any)</li>
101
	 * <li>clean deploy folder (if any). If it can be cleaned, schedules this
102
	 * for application exit</li>
103
	 * </ul>
104
	 * </p>
105
	 *
106
	 * @param resource
107
	 */
108
	private void cleanResource(MapResource resource) {
109
		if ((resource.deployFolder != null) && resource.deployFolder.exists()) {
110
			if (resource.mapContext != null) {
111
				resource.mapContext.dispose();
112
				resource.mapContext = null;
113
			}
114
			try {
115
				FileUtils.forceDelete(resource.deployFolder);
116
			} catch (IOException e) {
117
				try {
118
					FileUtils.forceDeleteOnExit(resource.deployFolder);
119
				} catch (IOException e1) {
120
					// Do nothing
121
				}
122
				resource.deployFolder = null;
123 123

  
124
            }
125
            resource.openedMaps.clear();
126
        }
127
    }
124
			}
125
			resource.openedMaps.clear();
126
		}
127
	}
128 128

  
129
    /**
130
     * <p>
131
     * Clean all open resources
132
     * </p>
133
     */
134
    public void cleanAllResources() {
135
        Iterator<MapResource> iterator = resources.values().iterator();
136
        MapResource resource;
137
        while (iterator.hasNext()) {
138
            resource = iterator.next();
139
            cleanResource(resource);
140
            iterator.remove();
141
        }
142
    }
129
	/**
130
	 * <p>
131
	 * Clean all open resources
132
	 * </p>
133
	 */
134
	public void cleanAllResources() {
135
		Iterator<MapResource> iterator = resources.values().iterator();
136
		MapResource resource;
137
		while (iterator.hasNext()) {
138
			resource = iterator.next();
139
			cleanResource(resource);
140
			iterator.remove();
141
		}
142
	}
143 143

  
144
    /**
145
     * Gets {@link PortableViewInformation} from a {@link PortableView} file
146
     *
147
     * @param mapFile
148
     * @return
149
     */
150
    public PortableViewInformation getInfoOfFile(File mapFile) {
151
        MapResource resource = resources.get(mapFile);
152
        if (resource == null) {
153
            return null;
154
        } else
155
            if (checkFileUpdated(mapFile, resource)) {
156
                return null;
157
            }
158
        resource.used();
159
        return resource.mapInformation;
160
    }
144
	/**
145
	 * Gets {@link PortableViewInformation} from a {@link PortableView} file
146
	 *
147
	 * @param mapFile
148
	 * @return
149
	 */
150
	public PortableViewInformation getInfoOfFile(File mapFile) {
151
		MapResource resource = resources.get(mapFile);
152
		if (resource == null) {
153
			return null;
154
		} else if (checkFileUpdated(mapFile, resource)) {
155
			return null;
156
		}
157
		resource.used();
158
		return resource.mapInformation;
159
	}
161 160

  
162
    /**
163
     * Checks if map file has been updated from last time resource has been
164
     * loaded
165
     *
166
     * @param mapFile
167
     * @param resource
168
     * @return
169
     */
170
    private boolean checkFileUpdated(File mapFile, MapResource resource) {
171
        if (FileUtils.isFileNewer(mapFile, resource.sourceLastUpdate)) {
172
            cleanResource(resource);
173
            resources.remove(mapFile);
174
            return true;
175
        }
176
        return false;
177
    }
161
	/**
162
	 * Checks if map file has been updated from last time resource has been
163
	 * loaded
164
	 *
165
	 * @param mapFile
166
	 * @param resource
167
	 * @return
168
	 */
169
	private boolean checkFileUpdated(File mapFile, MapResource resource) {
170
		if (FileUtils.isFileNewer(mapFile, resource.sourceLastUpdate)) {
171
			cleanResource(resource);
172
			resources.remove(mapFile);
173
			return true;
174
		}
175
		return false;
176
	}
178 177

  
179
    /**
180
     * Adds a resource to the pool
181
     *
182
     * @param map
183
     */
184
    public void addResource(DefaultPortableView map) {
185
        MapResource resource = resources.get(map.getSourceFile());
186
        File source = map.getSourceFile();
187
        if ((resource != null) && !checkFileUpdated(source, resource)) {
188
            return;
189
        } else {
190
            resource = createResource(map);
191
        }
192
        resource.used();
193
    }
178
	/**
179
	 * Adds a resource to the pool
180
	 *
181
	 * @param map
182
	 */
183
	public void addResource(DefaultPortableView map) {
184
		MapResource resource = resources.get(map.getSourceFile());
185
		File source = map.getSourceFile();
186
		if ((resource != null) && !checkFileUpdated(source, resource)) {
187
			return;
188
		} else {
189
			resource = createResource(map);
190
		}
191
		resource.used();
192
	}
194 193

  
195
    /**
196
     * Create a {@link MapResource} instance from a {@link PortableView}
197
     *
198
     * @param map
199
     * @return
200
     */
201
    private MapResource createResource(DefaultPortableView map) {
202
        MapResource resource = new MapResource();
203
        File source = map.getSourceFile();
204
        resource.sourceFile = source;
205
        resource.sourceLastUpdate =
206
            new Date(resource.sourceFile.lastModified());
207
        resource.mapInformation = map.getInformation();
208
        resource.openedMaps =
209
            new ArrayList<WeakReference<DefaultPortableView>>();
194
	/**
195
	 * Create a {@link MapResource} instance from a {@link PortableView}
196
	 *
197
	 * @param map
198
	 * @return
199
	 */
200
	private MapResource createResource(DefaultPortableView map) {
201
		MapResource resource = new MapResource();
202
		File source = map.getSourceFile();
203
		resource.sourceFile = source;
204
		resource.sourceLastUpdate = new Date(resource.sourceFile.lastModified());
205
		resource.mapInformation = map.getInformation();
206
		resource.openedMaps = new ArrayList<WeakReference<DefaultPortableView>>();
210 207

  
211
        resources.put(source, resource);
212
        resource.used();
213
        return resource;
214
    }
208
		resources.put(source, resource);
209
		resource.used();
210
		return resource;
211
	}
215 212

  
216
    /**
217
     * Removed the oldest resources if pools contains more than
218
     * {@link #MAX_RESOUCES}
219
     *
220
     */
221
    public void adjustResourceSize() {
222
        if (resources.size() <= MAX_RESOUCES) {
223
            // Do nothing
224
            return;
225
        }
213
	/**
214
	 * Removed the oldest resources if pools contains more than
215
	 * {@link #MAX_RESOUCES}
216
	 *
217
	 */
218
	public void adjustResourceSize() {
219
		if (resources.size() <= MAX_RESOUCES) {
220
			// Do nothing
221
			return;
222
		}
226 223

  
227
        // Created a set sorted by last used (descending)
228
        SortedSet<MapResource> sorted =
229
            new TreeSet<MapResource>(new Comparator<MapResource>() {
224
		// Created a set sorted by last used (descending)
225
		SortedSet<MapResource> sorted = new TreeSet<MapResource>(
226
				new Comparator<MapResource>() {
230 227

  
231
                public int compare(MapResource o1, MapResource o2) {
232
                    return (int) ((o2.lastUsesTimestamp - o1.lastUsesTimestamp) * -1);
233
                }
234
            });
228
					public int compare(MapResource o1, MapResource o2) {
229
						return (int) ((o2.lastUsesTimestamp - o1.lastUsesTimestamp) * -1);
230
					}
231
				});
235 232

  
236
        // Target size to left in pool
237
        int targetSize = Math.min(MAX_RESOUCES - (MAX_RESOUCES / 15), 3);
233
		// Target size to left in pool
234
		int targetSize = Math.min(MAX_RESOUCES - (MAX_RESOUCES / 15), 3);
238 235

  
239
        // Add all resources to sort set
240
        sorted.addAll(resources.values());
241
        Iterator<MapResource> iter = sorted.iterator();
242
        MapResource resource;
236
		// Add all resources to sort set
237
		sorted.addAll(resources.values());
238
		Iterator<MapResource> iter = sorted.iterator();
239
		MapResource resource;
243 240

  
244
        // First pass: remove oldest, not-open resources
245
        while (iter.hasNext()) {
246
            resource = iter.next();
247
            if (resource.openedMaps.isEmpty()) {
248
                cleanResource(resource);
249
                resources.values().remove(resource);
250
                iter.remove();
251
            }
252
            if (resources.size() <= targetSize) {
253
                break;
254
            }
255
        }
256
        if (resources.size() > targetSize) {
257
            // TODO What do here?
258
        }
259
    }
241
		// First pass: remove oldest, not-open resources
242
		while (iter.hasNext()) {
243
			resource = iter.next();
244
			if (resource.openedMaps.isEmpty()) {
245
				cleanResource(resource);
246
				resources.values().remove(resource);
247
				iter.remove();
248
			}
249
			if (resources.size() <= targetSize) {
250
				break;
251
			}
252
		}
253
		if (resources.size() > targetSize) {
254
			// TODO What do here?
255
		}
256
	}
260 257

  
261
    /**
262
     * <p>
263
     * Opens a map
264
     * </p>
265
     * <p>
266
     * Deploy context of a {@link PortableView} file so it can be accessible if
267
     * it isn't done yet
268
     * </p>
269
     *
270
     * @param map
271
     * @return
272
     * @throws InvalidPortableViewFormatException
273
     * @throws CantLoadContextException
274
     * @throws IOException
275
     */
276
    public MapContext openMap(DefaultPortableView map)
277
        throws InvalidPortableViewFormatException, CantLoadContextException,
278
        IOException {
279
        File file = map.getSourceFile();
258
	/**
259
	 * <p>
260
	 * Opens a map
261
	 * </p>
262
	 * <p>
263
	 * Deploy context of a {@link PortableView} file so it can be accessible if
264
	 * it isn't done yet
265
	 * </p>
266
	 *
267
	 * @param map
268
	 * @return
269
	 * @throws InvalidPortableViewFormatException
270
	 * @throws CantLoadContextException
271
	 * @throws IOException
272
	 */
273
	public MapContext openMap(DefaultPortableView map)
274
			throws InvalidPortableViewFormatException,
275
			CantLoadContextException, IOException {
276
		File file = map.getSourceFile();
280 277

  
281
        // get map resource
282
        MapResource resource = resources.get(file);
283
        if (resource == null) {
284
            resource = createResource(map);
285
        }
278
		// get map resource
279
		MapResource resource = resources.get(file);
280
		if (resource == null) {
281
			resource = createResource(map);
282
		}
286 283

  
287
        if (resource.deployFolder == null) {
288
            // Generates a new deploy folder
289
            resource.deployFolder = generateDeployFolder(map.getSourceFile());
290
        }
291
        if (!resource.deployFolder.exists()) {
292
            // Creates it if it's needed
293
            resource.deployFolder.mkdirs();
294
        }
295
        if (resource.openedMaps.isEmpty()) {
296
            // if it's not deployed yet, unzips file into deploy folder
297
            FileUtils.unzipFile(file, resource.deployFolder);
298
            loadMapContext(resource);
299
        }
300
        // Store this map instance into opened maps
301
        resource.openedMaps.add(new WeakReference<DefaultPortableView>(map));
284
		if (resource.deployFolder == null) {
285
			// Generates a new deploy folder
286
			resource.deployFolder = generateDeployFolder(map.getSourceFile());
287
		}
288
		if (!resource.deployFolder.exists()) {
289
			// Creates it if it's needed
290
			resource.deployFolder.mkdirs();
291
		}
292
		if (resource.openedMaps.isEmpty()) {
293
			// if it's not deployed yet, unzips file into deploy folder
294
			FileUtils.unzipFile(file, resource.deployFolder);
295
			loadMapContext(resource);
296
		}
297
		// Store this map instance into opened maps
298
		resource.openedMaps.add(new WeakReference<DefaultPortableView>(map));
302 299

  
303
        // Adjust resource pool size
304
        adjustResourceSize();
300
		// Adjust resource pool size
301
		adjustResourceSize();
305 302

  
306
        // Return the map context
307
        return resource.mapContext.cloneFMap();
308
    }
303
		// Return the map context
304
		try {
305
			return resource.mapContext.cloneFMap();
306
		} catch (RuntimeException ex) {
307
			// If something is wrong try to load it from file
308
			return newMapContext(resource);
309
		}
309 310

  
310
    /**
311
     * Loads the mapContext definition form a deployed portable view folder
312
     *
313
     * @param resource
314
     * @throws InvalidPortableViewFormatException
315
     * @throws CantLoadContextException
316
     */
317
    private void loadMapContext(MapResource resource)
318
        throws InvalidPortableViewFormatException, CantLoadContextException {
319
        File deployFolder = resource.deployFolder;
320
        MapContext mapContext =
321
            mapLoader.loadMapContextFromMapDeployFolder(resource.sourceFile,
322
                deployFolder);
311
	}
323 312

  
324
        // Store mapContext in resource
325
        resource.mapContext = mapContext;
313
	private MapContext newMapContext(MapResource resource) throws InvalidPortableViewFormatException, CantLoadContextException {
314
		File deployFolder = resource.deployFolder;
315
		MapContext mapContext = mapLoader.loadMapContextFromMapDeployFolder(
316
				resource.sourceFile, deployFolder);
317
		return mapContext;
318
	}
326 319

  
327
        // Reset usage timestamp
328
        resource.used();
329
    }
320
	/**
321
	 * Loads the mapContext definition form a deployed portable view folder
322
	 *
323
	 * @param resource
324
	 * @throws InvalidPortableViewFormatException
325
	 * @throws CantLoadContextException
326
	 */
327
	private void loadMapContext(MapResource resource)
328
			throws InvalidPortableViewFormatException, CantLoadContextException {
330 329

  
331
    /**
332
     * Create a new folder to deploy a portable view
333
     *
334
     * @param source
335
     * @return
336
     */
337
    private File generateDeployFolder(File source) {
338
        File base =
339
            new File(PortableViewLocator.getManager().getTemporalFolder());
340
        String folderName = source.getName();
341
        return FileUtils.getNewWritableFolder(base, folderName);
342
    }
330
		// Store mapContext in resource
331
		resource.mapContext = newMapContext(resource);
343 332

  
344
    /**
345
     * Remove portable view instance form opened map register of resource. Cleans
346
     * deploy folder if there is no more instance map opened
347
     *
348
     * @param map
349
     */
350
    public void closeMap(DefaultPortableView map) {
351
        File file = map.getSourceFile();
352
        MapResource resource = resources.get(file);
353
        if (resource == null) {
354
            resource = createResource(map);
355
            return;
356
        }
357
        // Clean dead References in resource
358
        cleanDeadMapReferences(resource);
359
        Iterator<WeakReference<DefaultPortableView>> iter =
360
            resource.openedMaps.iterator();
361
        // Look for map instance and removes it
362
        while (iter.hasNext()) {
363
            if (map.equals(iter.next().get())) {
364
                iter.remove();
365
                break;
366
            }
367
        }
368
        if (resource.openedMaps.isEmpty()) {
369
            // If no more map instance opened, clean resource
370
            cleanResource(resource);
371
        }
372
        // reset usage timestamp
373
        resource.used();
333
		// Reset usage timestamp
334
		resource.used();
335
	}
374 336

  
375
        // Adjust resource pool size
376
        adjustResourceSize();
377
    }
337
	/**
338
	 * Create a new folder to deploy a portable view
339
	 *
340
	 * @param source
341
	 * @return
342
	 */
343
	private File generateDeployFolder(File source) {
344
		File base = new File(PortableViewLocator.getManager()
345
				.getTemporalFolder());
346
		String folderName = source.getName();
347
		return FileUtils.getNewWritableFolder(base, folderName);
348
	}
378 349

  
379
    /**
380
     * Cleans all dead weak references to Portable view opened form all resources
381
     */
382
    public void cleanDeadMapReferences() {
383
        for (MapResource resource : resources.values()) {
384
            cleanDeadMapReferences(resource);
385
        }
386
    }
350
	/**
351
	 * Remove portable view instance form opened map register of resource.
352
	 * Cleans deploy folder if there is no more instance map opened
353
	 *
354
	 * @param map
355
	 */
356
	public void closeMap(DefaultPortableView map) {
357
		File file = map.getSourceFile();
358
		MapResource resource = resources.get(file);
359
		if (resource == null) {
360
			resource = createResource(map);
361
			return;
362
		}
363
		// Clean dead References in resource
364
		cleanDeadMapReferences(resource);
365
		Iterator<WeakReference<DefaultPortableView>> iter = resource.openedMaps
366
				.iterator();
367
		// Look for map instance and removes it
368
		while (iter.hasNext()) {
369
			if (map.equals(iter.next().get())) {
370
				iter.remove();
371
				break;
372
			}
373
		}
374
		if (resource.openedMaps.isEmpty()) {
375
			// If no more map instance opened, clean resource
376
			cleanResource(resource);
377
		}
378
		// reset usage timestamp
379
		resource.used();
387 380

  
388
    /**
389
     * Cleans all dead weak references to Portable view opened form all resource
390
     * instance
391
     *
392
     * @param resource
393
     */
394
    private void cleanDeadMapReferences(MapResource resource) {
395
        Iterator<WeakReference<DefaultPortableView>> iter =
396
            resource.openedMaps.iterator();
397
        while (iter.hasNext()) {
398
            if (iter.next().get() == null) {
399
                iter.remove();
400
            }
401
        }
402
    }
381
		// Adjust resource pool size
382
		adjustResourceSize();
383
	}
403 384

  
404
    /**
405
     * Informs if a Portable view instance has been open
406
     *
407
     * @param map
408
     * @return
409
     */
410
    public boolean isOpen(DefaultPortableView map) {
411
        File file = map.getSourceFile();
412
        MapResource resource = resources.get(file);
413
        if (resource == null) {
414
            resource = createResource(map);
415
            return false;
416
        }
417
        resource.used();
418
        cleanDeadMapReferences(resource);
419
        for (WeakReference<DefaultPortableView> wrMap : resource.openedMaps) {
420
            if (map.equals(wrMap.get())) {
421
                return true;
422
            }
423
        }
424
        return false;
425
    }
385
	/**
386
	 * Cleans all dead weak references to Portable view opened form all
387
	 * resources
388
	 */
389
	public void cleanDeadMapReferences() {
390
		for (MapResource resource : resources.values()) {
391
			cleanDeadMapReferences(resource);
392
		}
393
	}
426 394

  
427
    /** {@inheridDoc} */
428
    public void dispose() {
429
        cleanAllResources();
430
        ToolsLocator.getDisposableManager().release(this);
431
    }
395
	/**
396
	 * Cleans all dead weak references to Portable view opened form all resource
397
	 * instance
398
	 *
399
	 * @param resource
400
	 */
401
	private void cleanDeadMapReferences(MapResource resource) {
402
		Iterator<WeakReference<DefaultPortableView>> iter = resource.openedMaps
403
				.iterator();
404
		while (iter.hasNext()) {
405
			if (iter.next().get() == null) {
406
				iter.remove();
407
			}
408
		}
409
	}
432 410

  
433
    /**
434
     * Represents a {@link PortableView} resource
435
     *
436
     * @author gvSIG Team
437
     * @version $Id$
438
     *
439
     */
440
    private class MapResource {
411
	/**
412
	 * Informs if a Portable view instance has been open
413
	 *
414
	 * @param map
415
	 * @return
416
	 */
417
	public boolean isOpen(DefaultPortableView map) {
418
		File file = map.getSourceFile();
419
		MapResource resource = resources.get(file);
420
		if (resource == null) {
421
			resource = createResource(map);
422
			return false;
423
		}
424
		resource.used();
425
		cleanDeadMapReferences(resource);
426
		for (WeakReference<DefaultPortableView> wrMap : resource.openedMaps) {
427
			if (map.equals(wrMap.get())) {
428
				return true;
429
			}
430
		}
431
		return false;
432
	}
441 433

  
442
        File sourceFile;
443
        Date sourceLastUpdate;
444
        MapContext mapContext;
445
        PortableViewInformation mapInformation;
446
        File deployFolder;
447
        List<WeakReference<DefaultPortableView>> openedMaps;
448
        long lastUsesTimestamp = 0;
434
	/** {@inheridDoc} */
435
	public void dispose() {
436
		cleanAllResources();
437
		ToolsLocator.getDisposableManager().release(this);
438
	}
449 439

  
450
        void used() {
451
            lastUsesTimestamp = System.currentTimeMillis();
452
        }
453
    }
440
	/**
441
	 * Represents a {@link PortableView} resource
442
	 *
443
	 * @author gvSIG Team
444
	 * @version $Id$
445
	 *
446
	 */
447
	private class MapResource {
454 448

  
449
		File sourceFile;
450
		Date sourceLastUpdate;
451
		MapContext mapContext;
452
		PortableViewInformation mapInformation;
453
		File deployFolder;
454
		List<WeakReference<DefaultPortableView>> openedMaps;
455
		long lastUsesTimestamp = 0;
456

  
457
		void used() {
458
			lastUsesTimestamp = System.currentTimeMillis();
459
		}
460
	}
461

  
455 462
}
org.gvsig.educa.portableview/trunk/org.gvsig.educa.portableview/org.gvsig.educa.portableview.swing/org.gvsig.educa.portableview.swing.api/src/main/java/org/gvsig/educa/portableview/swing/viewer/PortableViewTocImageProvider.java
28 28

  
29 29
/**
30 30
 * Interface for object which provides images for toc tree elements
31
 * 
31
 *
32 32
 * @author gvSIG Team
33 33
 * @version $Id$
34
 * 
34
 *
35 35
 */
36 36
public interface PortableViewTocImageProvider {
37 37

  
38 38
    /**
39 39
     * Gets image icon which represents the layer (usually depending on layer
40 40
     * type)
41
     * 
41
     *
42 42
     * @param layer
43 43
     * @return image or null if there is not especial image for this layer
44 44
     */
......
46 46

  
47 47
    /**
48 48
     * Gets a image preview of how this symbol looks
49
     * 
49
     *
50 50
     * @param symbol
51 51
     * @param sourceLayer
52 52
     * @return preview image or null to use a standard one
53 53
     */
54 54
    ImageIcon getSymbolPreview(ISymbol symbol, FLayer sourceLayer);
55 55

  
56
    /**
57
     * Gets a unavailable icon for unavailable layers
58
     *
59
     * @return unavailable image
60
     */
61
	ImageIcon getUnavailableIconForLayer();
62

  
56 63
}
org.gvsig.educa.portableview/trunk/org.gvsig.educa.portableview/org.gvsig.educa.portableview.swing/org.gvsig.educa.portableview.swing.impl/src/main/java/org/gvsig/educa/portableview/swing/impl/viewer/TocTreeCellRenderer.java
48 48
import org.gvsig.fmap.mapcontext.layers.FLayer;
49 49
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
50 50
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
51

  
51
import org.gvsig.andami.IconThemeHelper;
52 52
/**
53 53
 * <p>
54 54
 * Tree cell renderer for {@link DefaultPortableViewLayersEditor} JTree
......
327 327
     */
328 328
    private ImageIcon getImageForLayer(FLayer layer) {
329 329
        ImageIcon icon = null;
330
        if (imageProvider != null) {
330
        if(!layer.isAvailable()){
331
        	icon = IconThemeHelper.getImageIcon("layer-icon-unavailable");
332
        }else if (imageProvider != null) {
331 333
            icon = imageProvider.getImageIconForLayer(layer);
332 334
        }
333 335
        return icon;
org.gvsig.educa.portableview/trunk/org.gvsig.educa.portableview/org.gvsig.educa.portableview.swing/org.gvsig.educa.portableview.swing.impl/pom.xml
23 23
  		<groupId>org.gvsig</groupId>
24 24
  		<artifactId>org.gvsig.educa.portableview.lib.api</artifactId>
25 25
  	</dependency>
26
  	<dependency>
27
  		<groupId>org.gvsig</groupId>
28
  		<artifactId>org.gvsig.andami</artifactId>
29
  	</dependency>
26 30
  </dependencies>
27 31
</project>

Also available in: Unified diff