/** * Copyright (c) 2009 Juwi MacMillan Group GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.juwimm.cms.content.modules; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Iterator; import java.util.Properties; import javax.swing.event.EventListenerList; import org.apache.log4j.Logger; import org.xml.sax.ContentHandler; import de.juwimm.cms.content.event.EditpaneFiredEvent; import de.juwimm.cms.content.event.EditpaneFiredListener; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2002</p> * <p>Company: </p> * @author <a href="mailto:s.kulawik@juwimm.com">Sascha-Matthias Kulawik</a> * @version $Id$ */ public abstract class AbstractModule implements Module, Cloneable { private static Logger log = Logger.getLogger(AbstractModule.class); private boolean mandatory = false; private String dcfname = ""; private String label = ""; private String description = ""; private EventListenerList listenerList = new EventListenerList(); private String errMsg = ""; private String rootnodeName = ""; private ArrayList<Object[]> customProperties = new ArrayList<Object[]>(); private boolean customConfigurationReady = false; private boolean isLoaded = false; private boolean saveable = true; /** * Timestamp is used to specify unique dcf module in iteration */ private long timeStamp = 0; public final long getTimeStamp() { return this.timeStamp; } public final void setTimeStamp(long newTimeStamp) { this.timeStamp = newTimeStamp; } public String getRootnodeName() { return this.rootnodeName; } public void setRootnodeName(String newRootnodeName) { rootnodeName = newRootnodeName; } public final boolean isMandatory() { return this.mandatory; } public void setMandatory(boolean isMandatory) { this.mandatory = isMandatory; } public String getValidationError() { return errMsg; } /** * This Method should be called from within the Module to set the Errormessage, if there is one occuring.<br> * The Method getValidationError will call the isValid Method - * in this Method the validation should be checked and<br> * the Module itself should set the ValidationError afterwords. * * @param errorMessage The errormessage */ protected final void setValidationError(String errorMessage) { if (errorMessage == null) { this.errMsg = ""; } else { this.errMsg = errorMessage; } } /** * Method for APPENDING an errormessage to the current one.<br> * This is needful if you won't check everytime you append one errormessage to a big errormessage, * if there is one in and if you need to append a carriage return to that String.<br> * PLEASE MAKE SURE, that the errormessage was peviously resetted by setting setValidationError("")! * * @param errMsg The errormessage to append */ protected final void appendValidationError(String appendMsg) { if (appendMsg != null) { if (errMsg.equals("")) { errMsg = appendMsg; } else { errMsg += "\n" + appendMsg; } } } public final void setName(String moduleDcfname) { this.dcfname = moduleDcfname; } public final String getName() { return this.dcfname; } public final void setLabel(String dcfconfiglabel) { this.label = dcfconfiglabel; } public final String getLabel() { return this.label; } public final void setDescription(String userdescription) { this.description = userdescription; } public final String getDescription() { return this.description; } /** * This encodes a String with URL Encoding and should be used in general. * @param url * @return The encoded String. */ public static final String getURLEncoded(String url) { String retVal = url; try { retVal = URLEncoder.encode(url, "UTF-8"); retVal = retVal.replaceAll("[+]", "%20"); retVal = retVal.replaceAll("(%2F)", "%20"); // Slash is now a Space } catch (UnsupportedEncodingException exe) { log.error("UNSUPPORTED ENCODING UTF-8!", exe); } return retVal; } /** * This encodes a URL with URLEncoding for using URLs in Attributes of XML Files.<br> * This MUST be a valid URL! * @param urlTxt * @return URL */ public static final String getURLURLEncoded(String urlTxt) { try { URL url = new URL(urlTxt); String retVal = url.getPath(); try { String q = url.getQuery(); if (q == null || q.equals("")) { retVal = URLEncoder.encode(url.getPath(), "UTF-8"); } else { retVal = URLEncoder.encode(url.getPath() + "?" + q, "UTF-8"); } retVal = retVal.replaceAll("%2F", "/"); retVal = retVal.replaceAll("%3F", "?"); retVal = retVal.replaceAll("%3D", "="); retVal = retVal.replaceAll("%26", "&"); } catch (UnsupportedEncodingException exe) { log.error("UNSUPPORTED ENCODING UTF-8!", exe); } String adr = url.getProtocol() + "://" + url.getHost() + retVal; return adr; } catch (Exception exe) { } return ""; } /** * This encodes a String with ISO-8859-1 encoding and should be only used for the SVG Images - * this means <b>the only use of this method is in getPaneImage()!</b> * @param url The url to encode * @return The encoded String */ public static final String getURLEncodedISO(String url) { String retVal = url; try { retVal = URLEncoder.encode(url, "ISO-8859-1"); int fss = retVal.indexOf('.'); if (fss != -1) { retVal = retVal.substring(0, fss) + "." + retVal.substring(fss).replaceAll("\\.", ""); } retVal = retVal.replaceAll("[+]", "%20"); retVal = retVal.replaceAll("(%2F)", "%20"); // Slash is now a Space } catch (UnsupportedEncodingException exe) { log.error("UNSUPPORTED ENCODING ISO-8859-1!", exe); } return retVal; } public static final String getURLDecoded(String encodedString) { String retVal = encodedString; try { retVal = URLDecoder.decode(encodedString, "UTF-8"); } catch (UnsupportedEncodingException exe) { log.error("UNSUPPORTED ENCODING UTF-8!", exe); } return retVal; } /** * Method for adding a listener for all save-operations of the guibuilder. * These Listeners are saved until the GuibuilderSingleton Instance will be dropped. * @param sav The SaveOperationListener Object */ public final void addEditpaneFiredListener(EditpaneFiredListener sav) { this.listenerList.add(EditpaneFiredListener.class, sav); } /** * Method for removing a listener for all save-operations. * @param sav The SaveOperationListener Object */ public final void removeEditpaneFiredListener(EditpaneFiredListener sav) { this.listenerList.remove(EditpaneFiredListener.class, sav); } public final boolean hasEditpaneFiredListener() { if (this.listenerList.getListenerCount(EditpaneFiredListener.class) > 0) { return true; } return false; } public final void runEditpaneFiredEvent(EditpaneFiredEvent efe) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 1; i >= 0; i --) { if(listeners[i] instanceof EditpaneFiredListener){ ((EditpaneFiredListener) listeners[i]).editpaneFiredPerformed(efe); } } } public final void runEditpaneCancelEvent(EditpaneFiredEvent efe) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { ((EditpaneFiredListener) listeners[i + 1]).editpaneCancelPerformed(efe); } } /** * This Implementation is only for "cloning-purposes" and should be overwritten if you need some custom values.<br/> * Please beware, that you call this method during your overwriting with super.setCustomProperties() * * @param methodName * @param parameters */ public void setCustomProperties(String methodName, Properties parameters) { customProperties.add(new Object[] {methodName, parameters}); if (methodName.equals("CustomConfigurationReady")) { this.customConfigurationReady = true; } } public boolean isCustomConfigurationReady() { return this.customConfigurationReady; } public void waitWhileCustomConfigurationIsntReady() { try { Thread t = new Thread("Wait-For-Custom-Configuration") { public void run() { try { while (!customConfigurationReady) { Thread.sleep(20); } } catch (Exception exe) { } } }; t.setPriority(Thread.NORM_PRIORITY); t.start(); t.join(); } catch (Exception exe) { } } public void waitWhileIsntLoaded() { try { Thread t = new Thread() { public void run() { try { while (!customConfigurationReady) { Thread.sleep(20); } } catch (Exception exe) { } } }; t.setPriority(Thread.NORM_PRIORITY); t.start(); t.join(); } catch (Exception exe) { } } /** * @param isLoaded The isLoaded to set. */ protected void setLoaded(boolean isLoaded) { this.isLoaded = isLoaded; } /** * @return Returns the isLoaded. */ protected boolean isLoaded() { return isLoaded; } public Object clone() { return clone(true); } public Object clone(boolean cloneAndSetProperties) { waitWhileCustomConfigurationIsntReady(); Module module = null; try { module = this.getClass().newInstance(); Iterator it = customProperties.iterator(); boolean sendCCR = true; while (it.hasNext()) { Object[] cpr = (Object[]) it.next(); module.setCustomProperties((String) cpr[0], (Properties) cpr[1]); if ("CustomConfigurationReady".equalsIgnoreCase((String) cpr[0])) sendCCR = false; } if (sendCCR) module.setCustomProperties("CustomConfigurationReady", new Properties()); module.setRootnodeName(this.getRootnodeName()); module.setDescription(this.getDescription()); module.setLabel(this.getLabel()); module.setMandatory(this.isMandatory()); module.setName(this.getName()); //module.setCustomProperties(); if (cloneAndSetProperties) module.setProperties(this.getProperties()); } catch (Exception exe) { log.error("Error during the clone phase of the module", exe); } return module; } /** * @return Returns the saveable. */ public final boolean isSaveable() { return this.saveable; } /** * @param isSaveable The saveable to set. */ public final void setSaveable(boolean isSaveable) { this.saveable = isSaveable; } /* (non-Javadoc) * @see de.juwimm.cms.content.modules.Module#load(org.xml.sax.ContentHandler) */ public void load(ContentHandler ch) { throw new UnsupportedOperationException("actually not supported"); } /* (non-Javadoc) * @see de.juwimm.cms.content.modules.Module#save(org.xml.sax.ContentHandler) */ public void save(ContentHandler contentHandler) { throw new UnsupportedOperationException("actually not supported"); } }