001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI for
003: * visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or modify it under
008: * the terms of the GNU General Public License as published by the Free Software
009: * Foundation; either version 2 of the License, or (at your option) any later
010: * version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
014: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
015: * details.
016: *
017: * You should have received a copy of the GNU General Public License along with
018: * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
019: * Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions Suite #1A 2328 Government Street Victoria BC V8T 5G5 Canada
024: *
025: * (250)385-6040 www.vividsolutions.com
026: */
027:
028: package com.vividsolutions.jump.workbench.ui.plugin;
029:
030: import java.io.File;
031: import java.io.FileReader;
032: import java.util.ArrayList;
033: import java.util.Collections;
034: import java.util.Iterator;
035: import java.util.Vector;
036: import java.io.FileNotFoundException;
037:
038: import javax.swing.JFileChooser;
039: import javax.swing.filechooser.FileFilter;
040: import java.util.Map;
041: import javax.swing.JOptionPane;
042:
043: import com.vividsolutions.jump.I18N;
044: import com.vividsolutions.jump.coordsys.CoordinateSystemRegistry;
045: import com.vividsolutions.jump.feature.FeatureCollection;
046: import com.vividsolutions.jump.io.datasource.Connection;
047: import com.vividsolutions.jump.io.datasource.DataSource;
048: import com.vividsolutions.jump.task.TaskMonitor;
049: import com.vividsolutions.jump.util.java2xml.XML2Java;
050: import com.vividsolutions.jump.workbench.WorkbenchContext;
051: import com.vividsolutions.jump.workbench.model.Category;
052: import com.vividsolutions.jump.workbench.model.Layer;
053: import com.vividsolutions.jump.workbench.model.LayerManager;
054: import com.vividsolutions.jump.workbench.model.Layerable;
055: import com.vividsolutions.jump.workbench.model.Task;
056: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
057: import com.vividsolutions.jump.workbench.plugin.ThreadedBasePlugIn;
058: import com.vividsolutions.jump.workbench.ui.GUIUtil;
059: import com.vividsolutions.jump.workbench.ui.WorkbenchFrame;
060:
061: public class OpenProjectPlugIn extends ThreadedBasePlugIn {
062: private JFileChooser fileChooser;
063:
064: private Task newTask;
065:
066: private Task sourceTask;
067:
068: public OpenProjectPlugIn() {
069: }
070:
071: public String getName() {
072: return I18N.get("ui.plugin.OpenProjectPlugIn.open-project");
073: }
074:
075: public void initialize(PlugInContext context) throws Exception {
076: }
077:
078: private void initFileChooser() {
079: if (fileChooser != null)
080: return;
081:
082: //Don't initialize fileChooser in field declaration -- seems too early
083: // because
084: //we sometimes get a WindowsFileChooserUI NullPointerException [Jon
085: // Aquino 12/10/2003]
086: fileChooser = GUIUtil.createJFileChooserWithExistenceChecking();
087: fileChooser.setDialogTitle(I18N
088: .get("ui.plugin.OpenProjectPlugIn.open-project"));
089: fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
090: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
091: fileChooser.setMultiSelectionEnabled(false);
092: GUIUtil.removeChoosableFileFilters(fileChooser);
093: fileChooser
094: .addChoosableFileFilter(SaveProjectAsPlugIn.JUMP_PROJECT_FILE_FILTER);
095: fileChooser.addChoosableFileFilter(GUIUtil.ALL_FILES_FILTER);
096: fileChooser
097: .setFileFilter(SaveProjectAsPlugIn.JUMP_PROJECT_FILE_FILTER);
098: }
099:
100: public boolean execute(PlugInContext context) throws Exception {
101: initFileChooser();
102: reportNothingToUndoYet(context);
103:
104: if (JFileChooser.APPROVE_OPTION != fileChooser
105: .showOpenDialog(context.getWorkbenchFrame())) {
106: return false;
107: }
108: open(fileChooser.getSelectedFile(), context.getWorkbenchFrame());
109: return true;
110: }
111:
112: public void run(TaskMonitor monitor, PlugInContext context)
113: throws Exception {
114: loadLayers(context, sourceTask.getLayerManager(), newTask
115: .getLayerManager(),
116: CoordinateSystemRegistry.instance(context
117: .getWorkbenchContext().getBlackboard()),
118: monitor);
119: }
120:
121: public void open(File file, WorkbenchFrame workbenchFrame)
122: throws Exception {
123: FileReader reader = new FileReader(file);
124:
125: try {
126: sourceTask = (Task) new XML2Java(workbenchFrame
127: .getContext().getWorkbench().getPlugInManager()
128: .getClassLoader()).read(reader, Task.class);
129: //I can't remember why I'm creating a new Task instead of using
130: //sourceTask. There must be a good reason. [Jon Aquino]
131: // Probably to reverse the order of the layerables. See comments.
132: // Probably also to set the LayerManager coordinate system.
133: // [Jon Aquino 2005-03-16]
134: initializeDataSources(sourceTask, workbenchFrame
135: .getContext());
136: newTask = new Task();
137: newTask.setName(GUIUtil.nameWithoutExtension(file));
138: newTask.setProjectFile(file);
139: workbenchFrame.addTaskFrame(newTask);
140: } finally {
141: reader.close();
142: }
143: }
144:
145: private void initializeDataSources(Task task,
146: WorkbenchContext context) {
147: for (Iterator i = task.getLayerManager().getLayers().iterator(); i
148: .hasNext();) {
149: Layer layer = (Layer) i.next();
150: if (layer.getDataSourceQuery().getDataSource() instanceof WorkbenchContextReference) {
151: ((WorkbenchContextReference) layer.getDataSourceQuery()
152: .getDataSource()).setWorkbenchContext(context);
153: }
154: }
155: }
156:
157: private void loadLayers(PlugInContext context,
158: LayerManager sourceLayerManager,
159: LayerManager newLayerManager,
160: CoordinateSystemRegistry registry, TaskMonitor monitor)
161: throws Exception {
162: FindFile findFile = new FindFile(context);
163: boolean displayDialog = true;
164:
165: for (Iterator i = sourceLayerManager.getCategories().iterator(); i
166: .hasNext();) {
167: Category sourceLayerCategory = (Category) i.next();
168: // Explicitly add categories. Can't rely on
169: // LayerManager#addLayerable to add the categories, because a
170: // category might not have any layers. [Jon Aquino]
171: newLayerManager.addCategory(sourceLayerCategory.getName());
172:
173: // LayerManager#addLayerable adds layerables to the top. So reverse
174: // the order. [Jon Aquino]
175: ArrayList layerables = new ArrayList(sourceLayerCategory
176: .getLayerables());
177: Collections.reverse(layerables);
178:
179: for (Iterator j = layerables.iterator(); j.hasNext();) {
180: Layerable layerable = (Layerable) j.next();
181: if (monitor != null) {
182: monitor.report(I18N
183: .get("ui.plugin.OpenProjectPlugIn.loading")
184: + " " + layerable.getName());
185: }
186: layerable.setLayerManager(newLayerManager);
187:
188: if (layerable instanceof Layer) {
189: Layer layer = (Layer) layerable;
190: try {
191: load(layer, registry, monitor);
192: } catch (FileNotFoundException ex) {
193: if (displayDialog) {
194: displayDialog = false;
195:
196: int response = JOptionPane
197: .showConfirmDialog(
198: context.getWorkbenchFrame(),
199: I18N
200: .get("ui.plugin.OpenProjectPlugIn.At-least-one-file-in-the-task-could-not-be-found")
201: + "\n"
202: + I18N
203: .get("ui.plugin.OpenProjectPlugIn.Do-you-want-to-locate-it-and-continue-loading-the-task"),
204: "JUMP",
205: JOptionPane.YES_NO_OPTION);
206:
207: if (response != JOptionPane.YES_OPTION) {
208: break;
209: }
210: }
211:
212: String fname = layer.getDataSourceQuery()
213: .getDataSource().getProperties().get(
214: "File").toString();
215: String filename = findFile.getFileName(fname);
216: if (filename.length() > 0) {
217: //set the new source for this layer
218: Map properties = layer.getDataSourceQuery()
219: .getDataSource().getProperties();
220: properties.put(DataSource.FILE_KEY,
221: filename);
222: layer.getDataSourceQuery().getDataSource()
223: .setProperties(properties);
224: load(layer, registry, monitor);
225: } else {
226: break;
227: }
228: }
229: }
230:
231: newLayerManager.addLayerable(sourceLayerCategory
232: .getName(), layerable);
233: }
234: }
235: }
236:
237: public static void load(Layer layer,
238: CoordinateSystemRegistry registry, TaskMonitor monitor)
239: throws Exception {
240: layer.setFeatureCollection(executeQuery(layer
241: .getDataSourceQuery().getQuery(), layer
242: .getDataSourceQuery().getDataSource(), registry,
243: monitor));
244: layer.setFeatureCollectionModified(false);
245: }
246:
247: private static FeatureCollection executeQuery(String query,
248: DataSource dataSource, CoordinateSystemRegistry registry,
249: TaskMonitor monitor) throws Exception {
250: Connection connection = dataSource.getConnection();
251: try {
252: return dataSource.installCoordinateSystem(connection
253: .executeQuery(query, monitor), registry);
254: } finally {
255: connection.close();
256: }
257: }
258:
259: public class FindFile {
260: private Vector prefixList = new Vector(5, 5);
261: private JFileChooser fileChooser;
262: private PlugInContext context;
263:
264: public FindFile(PlugInContext context) {
265: this .context = context;
266: fileChooser = new JFileChooser();
267: fileChooser = GUIUtil
268: .createJFileChooserWithExistenceChecking();
269: fileChooser.setDialogTitle("Choose current location of: ");
270: fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
271: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
272: fileChooser.setMultiSelectionEnabled(false);
273: }
274:
275: public FindFile(PlugInContext context, JFileChooser fileChooser) {
276: this (context);
277: this .fileChooser = fileChooser;
278: }
279:
280: public String getFileName(String filenamepath) throws Exception {
281: //strip off file name
282: File oldFile = new File(filenamepath);
283: String oldPath = oldFile.getPath();
284: //see if something in the prefixList matches all or part of oldPath
285: for (Iterator i = prefixList.iterator(); i.hasNext();) {
286: PathPrefixes prefix = (PathPrefixes) i.next();
287: if (oldPath.toLowerCase().indexOf(
288: prefix.getOldPrefix().toLowerCase()) > -1) //found match
289: {
290: //replace matching portion with new prefix
291: String newFileNamePath = filenamepath
292: .substring(prefix.getOldPrefix().length());
293: newFileNamePath = prefix.getNewPrefix()
294: + newFileNamePath;
295: File newFile = new File(newFileNamePath);
296: if (newFile.exists())
297: return newFileNamePath;
298: //else continue to look through list
299: }
300: }
301:
302: //at this point didn't find a match
303: //ask user to find file
304: fileChooser.setDialogTitle("Choose current location of: "
305: + filenamepath);
306: GUIUtil.removeChoosableFileFilters(fileChooser);
307: fileChooser
308: .addChoosableFileFilter(GUIUtil.ALL_FILES_FILTER);
309: String ext = "";
310: int k = filenamepath.lastIndexOf('.');
311:
312: if ((k > 0) && (k < (filenamepath.length() - 1))) {
313: ext = filenamepath.substring(k + 1);
314: FileFilter fileFilter = GUIUtil.createFileFilter(ext
315: .toUpperCase()
316: + " Files", new String[] { ext.toLowerCase() });
317: fileChooser.addChoosableFileFilter(fileFilter);
318: fileChooser.setFileFilter(fileFilter);
319: }
320:
321: if (JFileChooser.APPROVE_OPTION == fileChooser
322: .showOpenDialog(context.getWorkbenchFrame())) {
323: String newParent = fileChooser.getSelectedFile()
324: .getParent()
325: + File.separator;
326: String oldParent = new File(filenamepath).getParent()
327: + File.separator;
328:
329: //find where they differ
330: int i = newParent.length();
331: int j = oldParent.length();
332: while (newParent.substring(i).equalsIgnoreCase(
333: oldParent.substring(j))) {
334: i--;
335: j--;
336: }
337: while (newParent.charAt(i) != File.separatorChar) {
338: i++;
339: }
340: while (oldParent.charAt(j) != File.separatorChar) {
341: j++;
342: }
343:
344: String newPrefix = newParent.substring(0, ++i);
345: String oldPrefix = oldParent.substring(0, ++j);
346:
347: PathPrefixes pathPrefix = new PathPrefixes(oldPrefix,
348: newPrefix);
349: prefixList.add(pathPrefix);
350: return fileChooser.getSelectedFile().getPath();
351: }
352: return ""; //user canceled find file
353: }
354: }
355:
356: public class PathPrefixes {
357: private String oldPrefix = "";
358: private String newPrefix = "";
359:
360: public PathPrefixes(String oldPrefix, String newPrefix) {
361: this .oldPrefix = oldPrefix;
362: this .newPrefix = newPrefix;
363: }
364:
365: public String getOldPrefix() {
366: return oldPrefix;
367: }
368:
369: public String getNewPrefix() {
370: return newPrefix;
371: }
372: }
373:
374: }
|