001: /*
002: * Created on 16.02.2005 for PIROL
003: *
004: * SVN header information:
005: * $Author: javamap $
006: * $Rev: 856 $
007: * $Date: 2007-06-18 21:15:27 -0700 (Mon, 18 Jun 2007) $
008: * $Id: StandardPirolPlugIn.java 856 2007-06-19 04:15:27Z javamap $
009: */
010: package de.fho.jump.pirol.utilities.plugIns;
011:
012: import java.awt.Image;
013: import java.awt.image.BufferedImage;
014: import java.io.IOException;
015: import java.io.InputStream;
016:
017: import javax.imageio.ImageIO;
018: import javax.swing.Icon;
019: import javax.swing.ImageIcon;
020:
021: import com.vividsolutions.jts.geom.GeometryFactory;
022: import com.vividsolutions.jump.feature.Feature;
023: import com.vividsolutions.jump.workbench.WorkbenchContext;
024: import com.vividsolutions.jump.workbench.model.Layer;
025: import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
026: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
027: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
028: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
029: import com.vividsolutions.jump.workbench.ui.ErrorHandler;
030: import com.vividsolutions.jump.workbench.ui.task.TaskMonitorDialog;
031:
032: import de.fho.jump.pirol.utilities.apiTools.FeatureCollectionTools;
033: import de.fho.jump.pirol.utilities.apiTools.LayerTools;
034: import de.fho.jump.pirol.utilities.apiTools.SelectionTools;
035: import de.fho.jump.pirol.utilities.debugOutput.PersonalLogger;
036: import de.fho.jump.pirol.utilities.i18n.PirolPlugInMessages;
037: import de.fho.jump.pirol.utilities.settings.PirolPlugInSettings;
038:
039: /**
040: * Overrides most of the abstract methods of the AbstractPlugIn to implement
041: * a default behavior, that fits the needs for a plugIn in the PIROL context.
042: * Also implements the ErrorHandler interface and offers methods to post error
043: * messages to the GUI.
044: *
045: * @author Ole Rahn, Stefan Ostermann
046: * <br>
047: * <br>FH Osnabrück - University of Applied Sciences Osnabrück,
048: * <br>Project: PIROL (2005),
049: * <br>Subproject: Daten- und Wissensmanagement
050: *
051: * @version $Rev: 856 $
052: *
053: */
054: public abstract class StandardPirolPlugIn extends AbstractPlugIn
055: implements ErrorHandler {
056:
057: /**
058: * buffer for messages of errors that occured during execution - needed to implement the ErrorHandler interface
059: */
060: protected StringBuffer messages = new StringBuffer();
061: /**
062: * Are errors to be shown in the statusbar (bringUpMessages = false, DEFAULT) or in an
063: * output window (bringUpMessages = true)?
064: */
065: protected boolean bringUpMessages = false;
066:
067: protected static EnableCheckFactory checkFactory = null;
068:
069: /**
070: * see description for method getIconString() for more information
071: */
072: protected ImageIcon icon = null;
073: protected boolean useToolIconSize = false;
074:
075: protected static GeometryFactory geometryFactory = new GeometryFactory();
076:
077: /**
078: * logger reference for use with the StandardPirolPlugIn. Since loggers are personalized, this member has to be
079: * initialized in derived classes by the programmer, before it can be used. For downward compatibility no abstract
080: * method or constructur parameter was introduced to do this.
081: * @since rev.1.12
082: */
083: protected PersonalLogger logger = null;
084:
085: /**
086: * Please, use this constructor in the deriving class!
087: *@param logger the logger that will controll console outputs
088: *@since rev.1.17
089: */
090: public StandardPirolPlugIn(PersonalLogger logger) {
091: super ();
092: this .logger = logger;
093: }
094:
095: public String getShortClassName() {
096: int pointPos = this .getClass().getName().lastIndexOf(".");
097: if (pointPos > -1) {
098: return this .getClass().getName().substring(
099: this .getClass().getName().lastIndexOf(".") + 1);
100: }
101: this .logger.printWarning("class name is very short: "
102: + this .getClass().getName());
103: return this .getClass().getName();
104: }
105:
106: public static MultiEnableCheck createEnableCheck(
107: final WorkbenchContext workbenchContext, boolean needFence) {
108: if (StandardPirolPlugIn.checkFactory == null) {
109: StandardPirolPlugIn.checkFactory = new EnableCheckFactory(
110: workbenchContext);
111: }
112: MultiEnableCheck multiEnableCheck = new MultiEnableCheck();
113:
114: multiEnableCheck.add(StandardPirolPlugIn.checkFactory
115: .createAtLeastNLayersMustExistCheck(1));
116: multiEnableCheck.add(StandardPirolPlugIn.checkFactory
117: .createAtLeastNLayersMustBeSelectedCheck(1));
118: if (needFence)
119: multiEnableCheck.add(StandardPirolPlugIn.checkFactory
120: .createFenceMustBeDrawnCheck());
121: return multiEnableCheck;
122: }
123:
124: /**
125: * Method to enable loading an icon from the surrounding jar-file if necessary.
126: * If the plugin doesn't need an icon, just return <code>null</code> else
127: * return the file name, e.g. "xyz.png" and put the picture in the same folder
128: * (package) as the deriving class.
129: * @return the filename of the icon or <code>null</code> if the plugin has no icon.
130: */
131: public abstract String getIconString();
132:
133: /**
134: * This method is called to execute the PlugIn.
135: * @return always <code>true</code> ?
136: * @param context the snapshot of the current workbench.
137: * @throws Exception
138: * @see com.vividsolutions.jump.workbench.plugin.AbstractPlugIn#execute(com.vividsolutions.jump.workbench.plugin.PlugInContext)
139: */
140: public abstract boolean execute(PlugInContext context)
141: throws Exception;
142:
143: /**
144: * Name of the PlugIn to be shown in the menus or as a tooltip in JUMP.<br>
145: * Looks for a key (the PlugIn's name with no path) in the i18n resources, if none is found
146: * the standard jump name generation will be used.
147: */
148: public String getName() {
149: try {
150: return PirolPlugInMessages.getString(this
151: .getShortClassName());
152: } catch (RuntimeException e) {
153: return super .getName();
154: }
155:
156: }
157:
158: /**
159: * The PlugIn will be added to the <code>PIROL Tools/<b>[return value of getCategoryName()]</b></code> menu and a standard {@link com.vividsolutions.jump.workbench.plugin.EnableCheck} is applied.
160: *@param context PlugInContext
161: *@throws Exception
162: *@see StandardPirolPlugIn#getCategoryName()
163: */
164: public void initialize(PlugInContext context) throws Exception {
165: context.getFeatureInstaller().addMainMenuItem(
166: this ,
167: new String[] { PirolPlugInSettings.getName_PirolMenu(),
168: getCategoryName() },
169: this .getName(),
170: false,
171: null,
172: StandardPirolPlugIn.createEnableCheck(context
173: .getWorkbenchContext(), false));
174: }
175:
176: /**
177: * The name of the category, a PlugIn can be found in - this method should be overridden by any derived class!
178: *@return name of the category, a PlugIn can be found in
179: */
180: public String getCategoryName() {
181: return PirolPlugInMessages.getString("unsorted");
182: }
183:
184: /**
185: * Standard intialization: PlugIn is added to the <code>PIROL Tools/<b>subMenuName</b></code> (or localized menu name) menu and a standard {@link com.vividsolutions.jump.workbench.plugin.EnableCheck} is applied.
186: * @deprecated
187: */
188: public void initialize(PlugInContext context, String subMenuName)
189: throws Exception {
190: if (this .logger != null)
191: this .logger.printDebug("subMenuName: " + subMenuName);
192: context.getFeatureInstaller().addMainMenuItem(
193: this ,
194: new String[] { PirolPlugInSettings.getName_PirolMenu(),
195: subMenuName },
196: this .getName(),
197: false,
198: null,
199: StandardPirolPlugIn.createEnableCheck(context
200: .getWorkbenchContext(), false));
201: }
202:
203: /**
204: *@param context the current PlugIn context
205: *@return a TaskMonitorDialog, to show progress information to the user
206: */
207: public static TaskMonitorDialog getMonitor(PlugInContext context) {
208: return new TaskMonitorDialog(context.getWorkbenchFrame(),
209: context.getWorkbenchFrame());
210: }
211:
212: /**
213: * Prints output to the stdout. Can be invoked by deriving classes.
214: * @param function the name of the method from within this one is called.
215: * E.g. "myMethod()".
216: * @param msg the message String.
217: * @see #println(Class, String, String)
218: * @deprecated use logger instead!
219: */
220: protected void println(String function, String msg) {
221: if (this .logger != null) {
222: this .logger.printDebug(msg);
223: } else {
224: println(this .getClass(), function, msg);
225: }
226: }
227:
228: /**
229: * Writes the given message and function string to the stdout.
230: * The output will be formated as "classname.function: message".
231: * @param c the calling class
232: * @param function the method from within this one is called.
233: * @param message the text with some useful information.
234: * @deprecated use logger instead!
235: */
236: public static void println(Class c, String function, String message) {
237: System.out.println(c.getName() + "." + function + "(): "
238: + message);
239: }
240:
241: /**
242: * Puts a warning message into the statusbar of JUMP
243: *@param context curr. PlugInContext
244: *@param msg message to be shown to the user
245: */
246: public static void warnUser(PlugInContext context, String msg) {
247: context.getWorkbenchFrame().warnUser(msg);
248: }
249:
250: /**
251: * Get a given number of selected Layers.
252: * @param context the current PlugInContext
253: * @param num max. number of layers to return, -1 returns all selected layers
254: * @return a given number of selected Layers, null if no Layers are selected
255: */
256: public static Layer[] getSelectedLayers(PlugInContext context,
257: int num) {
258: return LayerTools.getSelectedLayers(context, num);
259: }
260:
261: /**
262: * get one Layer that is selected
263: * @param context the current PlugInContext
264: * @return one selected Layer, null if no Layers are selected
265: */
266: public static Layer getSelectedLayer(PlugInContext context) {
267: return LayerTools.getSelectedLayer(context);
268: }
269:
270: /**
271: * To be called, when leaving the execute()-method. Puts out the error messages
272: * collected during execution if any and returns the given boolean value.
273: * Example:<pre>return finishExecution(context, true);</pre>
274: *@param context the current PlugInContext
275: *@param retVal the value to be returned by execute()
276: *@return retVal
277: */
278: protected boolean finishExecution(PlugInContext context,
279: boolean retVal) {
280: this .postMessagesToGui(context);
281: return retVal;
282: }
283:
284: protected void postMessagesToGui(PlugInContext context) {
285: if (messages.length() != 0 && context != null) {
286: context.getOutputFrame().createNewDocument();
287: context.getOutputFrame().addText(messages.toString());
288: if (bringUpMessages)
289: context.getOutputFrame().surface();
290: messages.delete(0, messages.length());
291: } else if (context == null) {
292: this .println("postMessagesToGui(PlugInContext context)",
293: "-> context == null!");
294: }
295: }
296:
297: public void handleThrowable(Throwable t) {
298: if (t.getMessage() == null || t.getMessage().equals("null")) {
299: StackTraceElement[] stre = t.getStackTrace();
300: for (int i = 0; i < stre.length; i++) {
301: messages.append(stre[i].toString() + "\n");
302: }
303: } else if (t.getMessage() != null) {
304: messages.append(t.getMessage() + "\n");
305: }
306: }
307:
308: /**
309: * Method to load an icon from the surrounding jar-file if necessary.
310: * @return the icon or <code>null</code> if the getIconString() returned null (or problems occured)
311: */
312: public Icon getIcon() {
313:
314: if (icon == null && this .getIconString() != null) {
315: InputStream in = this .getClass().getResourceAsStream(
316: this .getIconString());
317: BufferedImage img = null;
318: Image scaledImg = null;
319: try {
320: img = ImageIO.read(in);
321: scaledImg = img
322: .getScaledInstance(
323: this .useToolIconSize ? PirolPlugInSettings.StandardToolIconWidth
324: : PirolPlugInSettings.StandardPlugInIconWidth,
325: this .useToolIconSize ? PirolPlugInSettings.StandardToolIconHeight
326: : PirolPlugInSettings.StandardPlugInIconHeight,
327: img.getType());
328: } catch (IOException e) {
329: e.printStackTrace();
330: img = null;
331: icon = null;
332: }
333: if (scaledImg != null) {
334: icon = new ImageIcon(scaledImg);
335: }
336: }
337: return icon;
338: }
339:
340: /**
341: * Get a List of Features (from the given Layer) that reside within the fence (if there is a fence) or just the features of the layer
342: * (if there is currently no fence)
343: *@param context the plugIn context
344: *@param layer the layer holding the features
345: *@return List of features within fence if present or just within the layer
346: */
347: public static Feature[] getFeaturesInFenceOrInLayer(
348: PlugInContext context, Layer layer) {
349: SelectionTools st = new SelectionTools(context);
350: Feature[] featureToBeUsed = null;
351:
352: if (st.getFenceGeometry() == null) {
353: featureToBeUsed = FeatureCollectionTools
354: .FeatureCollection2FeatureArray(layer
355: .getFeatureCollectionWrapper()
356: .getUltimateWrappee());
357: } else {
358: featureToBeUsed = SelectionTools.getFeaturesInFenceInLayer(
359: layer, st.getFenceGeometry());
360: }
361:
362: return featureToBeUsed;
363: }
364:
365: /**
366: *@return the personal logger
367: *@see PersonalLogger
368: */
369: public PersonalLogger getLogger() {
370: return logger;
371: }
372:
373: /**
374: * Sets the personal logger - enables debug statement handling
375: *@param logger the new personal logger
376: *@see PersonalLogger
377: */
378: public void setLogger(PersonalLogger logger) {
379: this .logger = logger;
380: }
381:
382: public void setUseInToolbox(boolean toolboxUse) {
383: this.useToolIconSize = toolboxUse;
384: }
385: }
|