From 0ed2c1124cf1b9e49a2ec1fa0126a8df09f9e758 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 7 Oct 2014 09:18:11 +0200 Subject: Repackage to org.cristalise --- .../org/cristalise/kernel/utils/ActDefCache.java | 68 ++++ .../cristalise/kernel/utils/CastorArrayList.java | 74 ++++ .../org/cristalise/kernel/utils/CastorHashMap.java | 101 +++++ .../cristalise/kernel/utils/CastorXMLUtility.java | 188 +++++++++ .../org/cristalise/kernel/utils/DateUtility.java | 138 +++++++ .../cristalise/kernel/utils/DescriptionObject.java | 31 ++ .../kernel/utils/DescriptionObjectCache.java | 105 +++++ .../cristalise/kernel/utils/FileStringUtility.java | 450 +++++++++++++++++++++ .../kernel/utils/GTimeStampComparator.java | 46 +++ .../org/cristalise/kernel/utils/KeyValuePair.java | 107 +++++ .../java/org/cristalise/kernel/utils/Language.java | 86 ++++ .../cristalise/kernel/utils/LocalObjectLoader.java | 111 +++++ .../java/org/cristalise/kernel/utils/Logger.java | 207 ++++++++++ .../cristalise/kernel/utils/ObjectProperties.java | 215 ++++++++++ .../org/cristalise/kernel/utils/SoftCache.java | 139 +++++++ .../cristalise/kernel/utils/StateMachineCache.java | 67 +++ .../cristalise/kernel/utils/TransientCache.java | 149 +++++++ .../org/cristalise/kernel/utils/WeakCache.java | 154 +++++++ .../cristalise/kernel/utils/XmlElementParser.java | 125 ++++++ .../kernel/utils/server/SimpleTCPIPServer.java | 130 ++++++ .../kernel/utils/server/SocketHandler.java | 35 ++ 21 files changed, 2726 insertions(+) create mode 100644 src/main/java/org/cristalise/kernel/utils/ActDefCache.java create mode 100644 src/main/java/org/cristalise/kernel/utils/CastorArrayList.java create mode 100644 src/main/java/org/cristalise/kernel/utils/CastorHashMap.java create mode 100644 src/main/java/org/cristalise/kernel/utils/CastorXMLUtility.java create mode 100644 src/main/java/org/cristalise/kernel/utils/DateUtility.java create mode 100644 src/main/java/org/cristalise/kernel/utils/DescriptionObject.java create mode 100644 src/main/java/org/cristalise/kernel/utils/DescriptionObjectCache.java create mode 100644 src/main/java/org/cristalise/kernel/utils/FileStringUtility.java create mode 100644 src/main/java/org/cristalise/kernel/utils/GTimeStampComparator.java create mode 100644 src/main/java/org/cristalise/kernel/utils/KeyValuePair.java create mode 100644 src/main/java/org/cristalise/kernel/utils/Language.java create mode 100644 src/main/java/org/cristalise/kernel/utils/LocalObjectLoader.java create mode 100644 src/main/java/org/cristalise/kernel/utils/Logger.java create mode 100644 src/main/java/org/cristalise/kernel/utils/ObjectProperties.java create mode 100644 src/main/java/org/cristalise/kernel/utils/SoftCache.java create mode 100644 src/main/java/org/cristalise/kernel/utils/StateMachineCache.java create mode 100644 src/main/java/org/cristalise/kernel/utils/TransientCache.java create mode 100644 src/main/java/org/cristalise/kernel/utils/WeakCache.java create mode 100644 src/main/java/org/cristalise/kernel/utils/XmlElementParser.java create mode 100644 src/main/java/org/cristalise/kernel/utils/server/SimpleTCPIPServer.java create mode 100644 src/main/java/org/cristalise/kernel/utils/server/SocketHandler.java (limited to 'src/main/java/org/cristalise/kernel/utils') diff --git a/src/main/java/org/cristalise/kernel/utils/ActDefCache.java b/src/main/java/org/cristalise/kernel/utils/ActDefCache.java new file mode 100644 index 0000000..4cb5c8f --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/ActDefCache.java @@ -0,0 +1,68 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +/** + * + */ +package org.cristalise.kernel.utils; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.common.PersistencyException; +import org.cristalise.kernel.entity.proxy.ItemProxy; +import org.cristalise.kernel.lifecycle.ActivityDef; +import org.cristalise.kernel.persistency.ClusterStorage; +import org.cristalise.kernel.persistency.outcome.Viewpoint; +import org.cristalise.kernel.process.Gateway; + + +public class ActDefCache extends DescriptionObjectCache { + + + @Override + public String getDefRoot() { + return "/desc/ActivityDesc"; + } + + @Override + public ActivityDef loadObject(String name, int version, ItemProxy proxy) throws ObjectNotFoundException, InvalidDataException { + ActivityDef thisActDef; + String actType = proxy.getProperty("Complexity"); + Viewpoint actView = (Viewpoint)proxy.getObject(ClusterStorage.VIEWPOINT + "/" + actType + "ActivityDef/" + version); + String marshalledAct; + try { + marshalledAct = actView.getOutcome().getData(); + } catch (PersistencyException ex) { + Logger.error(ex); + throw new ObjectNotFoundException("Problem loading "+name+" v"+version+": "+ex.getMessage()); + } + try { + thisActDef = (ActivityDef)Gateway.getMarshaller().unmarshall(marshalledAct); + thisActDef.getProperties().put("Version", version); + } catch (Exception ex) { + Logger.error(ex); + throw new InvalidDataException("Could not unmarshall '"+name+"' v"+version+": "+ex.getMessage()); + } + thisActDef.setName(name); + thisActDef.setVersion(version); + return thisActDef; + } + +} \ No newline at end of file diff --git a/src/main/java/org/cristalise/kernel/utils/CastorArrayList.java b/src/main/java/org/cristalise/kernel/utils/CastorArrayList.java new file mode 100644 index 0000000..4a57bff --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/CastorArrayList.java @@ -0,0 +1,74 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.util.ArrayList; + +/************************************************************************** + * Wrapper for a root element to an ArrayList. Castor Marshalls arraylists + * as multiple elements, so this class is needed to provide a root element + * to stop it crashing. + * + * $Revision: 1.4 $ + * $Date: 2004/01/22 11:17:42 $ + * + * Copyright (C) 2003 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ +// +abstract public class CastorArrayList { + public ArrayList list; + + public CastorArrayList() { + super(); + list = new ArrayList(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((list == null) ? 0 : list.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CastorArrayList other = (CastorArrayList) obj; + if (list == null) { + if (other.list != null) + return false; + } else if (!list.equals(other.list)) + return false; + return true; + } + + public CastorArrayList(ArrayList list) { + this(); + this.list = list; + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/CastorHashMap.java b/src/main/java/org/cristalise/kernel/utils/CastorHashMap.java new file mode 100644 index 0000000..16dc90e --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/CastorHashMap.java @@ -0,0 +1,101 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + + +// This subclass of hashtable can be marshalled +// and unmarshalled with Castor +public class CastorHashMap extends HashMap +{ + public CastorHashMap() + { + clear(); + } + + ArrayList abstractPropNames = new ArrayList(); + + public KeyValuePair[] getKeyValuePairs() + { + int numKeys = size(); + + KeyValuePair[] keyValuePairs = new KeyValuePair[numKeys]; + Iterator keyIter = keySet().iterator(); + int i = 0; + + for(i=0; i(); + } + + + public void setKeyValuePair(KeyValuePair keyValuePair) + { + put(keyValuePair.getKey(), keyValuePair.getValue()); + if (keyValuePair.isAbstract()) + abstractPropNames.add(keyValuePair.getKey()); + else + abstractPropNames.remove(keyValuePair.getKey()); + } + + public ArrayList getAbstract() { + return abstractPropNames; + } + + + public void put(String key, Object value, boolean isAbstract) { + super.put(key, value); + if (isAbstract) + abstractPropNames.add(key); + else + abstractPropNames.remove(key); + + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/CastorXMLUtility.java b/src/main/java/org/cristalise/kernel/utils/CastorXMLUtility.java new file mode 100644 index 0000000..2d8ec9d --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/CastorXMLUtility.java @@ -0,0 +1,188 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +//Java +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashSet; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.persistency.outcome.Outcome; +import org.cristalise.kernel.process.resource.ResourceLoader; +import org.exolab.castor.mapping.Mapping; +import org.exolab.castor.mapping.MappingException; +import org.exolab.castor.xml.MarshalException; +import org.exolab.castor.xml.Marshaller; +import org.exolab.castor.xml.Unmarshaller; +import org.exolab.castor.xml.ValidationException; +import org.exolab.castor.xml.XMLContext; + + + +/************************************************************************** + * Loads all mapfiles, and wraps marshalling/unmarshalling + * + * @author $Author: abranson $ $Date: 2004/10/20 14:10:21 $ + * @version $Revision: 1.12 $ + **************************************************************************/ +public class CastorXMLUtility +{ + + public static final String CASTOR_XML_SERIALIZER_FACTORY = "org.exolab.castor.xml.serializer.factory"; + private XMLContext mappingContext; + + /** + * Looks for a file called 'index.xml' at the given URL, and loads every + * file listed in there by relative path + * + * @param aResourceLoader + * the resource loader able to return the right class loader + * @param aAppProperties + * the application properties containing optional castor + * configuration + * @param mapURL + * the root URL for the mapfiles + * @throws InvalidDataException + */ + public CastorXMLUtility(final ResourceLoader aResourceLoader, + final Properties aAppProperties, final URL mapURL) + throws InvalidDataException { + + + // load index + Logger.msg(3,String.format( "CastorXMLUtility. Loading maps from [%s]",mapURL)); + String index; + try { + index = FileStringUtility.url2String( new URL(mapURL, "index") ); + } catch (Exception e) { + throw new InvalidDataException(String.format("Could not load map index from [%s]",mapURL)); + } + + // retrieve the class loader of the class "CastorXMLUtility" + ClassLoader defaultClassLoader = aResourceLoader + .getClassLoader(CastorXMLUtility.class.getName()); + + Logger.msg(3, String.format( + "CastorXMLUtility.: defaultClassLoader=[%s]", + defaultClassLoader)); + + + StringTokenizer sTokenizer = new StringTokenizer(index); + int wNbMap = sTokenizer.countTokens(); + + // init the castor mapping using the classloader of the class "CastorXMLUtility" + Mapping thisMapping = new Mapping(defaultClassLoader); + HashSet loadedMapURLs = new HashSet(); + try { + int wMapIdx=0; + while( sTokenizer.hasMoreTokens() ) { + String thisMap = sTokenizer.nextToken(); + String thisMapURL = new URL(mapURL, thisMap).toString(); + wMapIdx++; + if( !loadedMapURLs.contains(thisMapURL) ) { + Logger.msg( 3, + String.format("CastorXMLUtility.: Adding mapping file (%d/%d):[%s]", wMapIdx, wNbMap, thisMapURL)); + thisMapping.loadMapping( new URL(thisMapURL) ); + loadedMapURLs.add( thisMapURL ); + } + else { + Logger.msg(3,"Map file already loaded:"+thisMapURL); + } + } + + mappingContext = new XMLContext(); + + mappingContext.setClassLoader(defaultClassLoader); + + // if the aAppProperties contains castor properties then + if (aAppProperties!= null && aAppProperties.containsKey(CASTOR_XML_SERIALIZER_FACTORY)) { + + mappingContext.setProperty(CASTOR_XML_SERIALIZER_FACTORY, + aAppProperties + .getProperty(CASTOR_XML_SERIALIZER_FACTORY)); + + Logger.msg(3, String.format( + "CastorXMLUtility.: castor prop: %s=[%s]", + CASTOR_XML_SERIALIZER_FACTORY, mappingContext + .getProperty(CASTOR_XML_SERIALIZER_FACTORY))); + + } + + mappingContext.addMapping(thisMapping); + } catch (MappingException ex) { + Logger.error(ex); + throw new InvalidDataException("XML Mapping files are not valid: "+ex.getMessage()); + } catch (MalformedURLException ex) { + Logger.error(ex); + throw new InvalidDataException("Mapping file location invalid: "+ex.getMessage()); + } catch (IOException ex) { + Logger.error(ex); + throw new InvalidDataException("Could not read XML mapping files: "+ex.getMessage()); + } + + Logger.msg(1, String.format("Loaded [%d] maps from [%s]", loadedMapURLs.size(), mapURL)); + } + + /************************************************************************** + * Marshalls a mapped object to string. The mapping must be loaded before. + * See updateMapping(). + **************************************************************************/ + public String marshall( Object obj ) + throws IOException, + MappingException, + MarshalException, + ValidationException + { + if (obj == null) return ""; + if (obj instanceof Outcome) + return ((Outcome)obj).getData(); + StringWriter sWriter = new StringWriter(); + Marshaller marshaller = mappingContext.createMarshaller(); + + marshaller.setWriter(sWriter); + marshaller.setMarshalAsDocument( false ); + marshaller.marshal( obj ); + + return sWriter.toString(); + } + + /************************************************************************** + * Unmarshalls a mapped object from string. The mapping must be loaded before. + * See updateMapping(). + **************************************************************************/ + public Object unmarshall( String data ) + throws IOException, + MappingException, + MarshalException, + ValidationException + { + if (data.equals("")) return null; + StringReader sReader = new StringReader( data ); + Unmarshaller unmarshaller = mappingContext.createUnmarshaller(); + return unmarshaller.unmarshal( sReader ); + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/DateUtility.java b/src/main/java/org/cristalise/kernel/utils/DateUtility.java new file mode 100644 index 0000000..faa77e3 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/DateUtility.java @@ -0,0 +1,138 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; +import org.cristalise.kernel.common.GTimeStamp; +/** + * @version $Revision: 1.8 $ $Date: 2005/05/10 15:14:55 $ + * @author $Author: abranson $ + */ +public class DateUtility +{ + public static GTimeStamp setToNow(GTimeStamp date) + { + java.util.Calendar now = java.util.Calendar.getInstance(); + date.mYear = now.get(java.util.Calendar.YEAR); + date.mMonth = now.get(java.util.Calendar.MONTH) + 1; + date.mDay = now.get(java.util.Calendar.DAY_OF_MONTH); + date.mHour = now.get(java.util.Calendar.HOUR_OF_DAY); + date.mMinute = now.get(java.util.Calendar.MINUTE); + date.mSecond = now.get(java.util.Calendar.SECOND); + date.mTimeOffset = now.get(java.util.Calendar.ZONE_OFFSET); + return date; + } + + public static String getSQLFormat(GTimeStamp timeStamp) + { + StringBuffer time = new StringBuffer().append(timeStamp.mYear).append("-"); + if (timeStamp.mMonth < 10) + time.append("0"); + time.append(timeStamp.mMonth).append("-"); + if (timeStamp.mDay < 10) + time.append("0"); + time.append(timeStamp.mDay).append(" "); + if (timeStamp.mHour < 10) + time.append("0"); + time.append(timeStamp.mHour).append(":"); + if (timeStamp.mMinute < 10) + time.append("0"); + time.append(timeStamp.mMinute).append(":"); + if (timeStamp.mSecond < 10) + time.append("0"); + time.append(timeStamp.mSecond); + return time.toString(); + } + + public static int getNbDayInYear(GTimeStamp date) + { + int centuary = date.mYear / 100; + int cdivby4 = centuary / 4; + int ydivby4 = date.mYear / 4; + if (centuary * 100 - date.mYear == 0) + { + if (centuary == cdivby4 * 4) + return 366; + else + return 365; + } + else if (date.mYear == ydivby4 * 4) + return 366; + else + return 365; + } + public static int getNbDayInMonth(GTimeStamp date) + { + switch (date.mMonth) + { + case 2 : + if (getNbDayInYear(date) == 365) + return 28; + else + return 29; + case 4 : + return 30; + case 6 : + return 30; + case 9 : + return 30; + case 11 : + return 30; + default : + return 31; + } + } + + public static long diff(GTimeStamp date1, GTimeStamp date2) + { + GTimeStamp tmp = new GTimeStamp(date1.mYear, date1.mMonth, date1.mDay, date1.mHour, date1.mMinute, date1.mSecond, date1.mTimeOffset); + while (tmp.mYear - date2.mYear < 0) + { + while (tmp.mMonth < 13) + { + tmp.mDay = tmp.mDay - getNbDayInMonth(tmp); + tmp.mMonth++; + } + tmp.mMonth = 1; + tmp.mYear++; + } + while (tmp.mYear - date2.mYear > 0) + { + while (tmp.mMonth > 1) + { + tmp.mMonth--; + tmp.mDay = tmp.mDay + getNbDayInMonth(tmp); + } + tmp.mMonth = 12; + tmp.mDay = tmp.mDay + getNbDayInMonth(tmp); + tmp.mYear--; + } + while (tmp.mMonth - date2.mMonth < 0) + { + tmp.mDay = tmp.mDay - getNbDayInMonth(tmp); + tmp.mMonth++; + } + while (tmp.mMonth - date2.mMonth > 0) + { + tmp.mMonth--; + tmp.mDay = tmp.mDay + getNbDayInMonth(tmp); + } + return (((tmp.mDay - date2.mDay) * 24 + tmp.mHour - date2.mHour) * 60 + tmp.mMinute - date2.mMinute) * 60 + tmp.mSecond - date2.mSecond; + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/DescriptionObject.java b/src/main/java/org/cristalise/kernel/utils/DescriptionObject.java new file mode 100644 index 0000000..5ae0dce --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/DescriptionObject.java @@ -0,0 +1,31 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +public interface DescriptionObject { + + public String getName(); + public int getVersion(); + + public void setName(String name); + public void setVersion(int version); + +} diff --git a/src/main/java/org/cristalise/kernel/utils/DescriptionObjectCache.java b/src/main/java/org/cristalise/kernel/utils/DescriptionObjectCache.java new file mode 100644 index 0000000..e5d0252 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/DescriptionObjectCache.java @@ -0,0 +1,105 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +/** + * + */ +package org.cristalise.kernel.utils; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.entity.proxy.ItemProxy; +import org.cristalise.kernel.entity.proxy.MemberSubscription; +import org.cristalise.kernel.entity.proxy.ProxyObserver; +import org.cristalise.kernel.persistency.ClusterStorage; +import org.cristalise.kernel.persistency.outcome.Viewpoint; + + +public abstract class DescriptionObjectCache { + + SoftCache> cache = new SoftCache>(); + + public D get(String name, int version) throws ObjectNotFoundException, InvalidDataException { + D thisDef; + synchronized(cache) { + CacheEntry thisDefEntry = cache.get(name+"_"+version); + if (thisDefEntry == null) { + Logger.msg(6, name+" v"+version+" not found in cache. Retrieving."); + ItemProxy defItem = LocalObjectLoader.loadLocalObjectDef(getDefRoot(), name); + thisDef = loadObject(name, version, defItem); + cache.put(name+"_"+version, new CacheEntry(thisDef, defItem, this)); + } + else { + Logger.msg(6, name+" v"+version+" found in cache."); + thisDef = thisDefEntry.def; + } + } + return thisDef; + } + + public abstract String getDefRoot(); + + public abstract D loadObject(String name, int version, ItemProxy proxy) throws ObjectNotFoundException, InvalidDataException; + + public void removeObject(String id) { + synchronized(cache) { + if (cache.keySet().contains(id)) { + Logger.msg(7, "ActDefCache: Removing activity def "+id+" from cache"); + cache.remove(id); + } + } + } + + public class CacheEntry implements ProxyObserver { + public String id; + public ItemProxy proxy; + public E def; + public DescriptionObjectCache parent; + public CacheEntry(E def, ItemProxy proxy, DescriptionObjectCache parent) { + this.id = def.getName()+"_"+def.getVersion(); + this.def = def; + this.parent = parent; + this.proxy = proxy; + proxy.subscribe(new MemberSubscription(this, ClusterStorage.VIEWPOINT, false)); + } + @Override + public void finalize() { + parent.removeObject(id); + proxy.unsubscribe(this); + } + @Override + public void add(Viewpoint contents) { + parent.removeObject(id); + } + + @Override + public void remove(String oldId) { + parent.removeObject(oldId); + } + + @Override + public String toString() { + return "Cache entry: "+id; + } + @Override + public void control(String control, String msg) { + } + } +} \ No newline at end of file diff --git a/src/main/java/org/cristalise/kernel/utils/FileStringUtility.java b/src/main/java/org/cristalise/kernel/utils/FileStringUtility.java new file mode 100644 index 0000000..3a87e74 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/FileStringUtility.java @@ -0,0 +1,450 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +//Java +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Array; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +/************************************************************************** + * + * @author $Author: abranson $ $Date: 2004/10/20 14:10:21 $ + * @version $Revision: 1.31 $ + **************************************************************************/ +public class FileStringUtility +{ + /************************************************************************** + * Reads a file and converts it to String + **************************************************************************/ + static public String file2String(File file) throws FileNotFoundException, IOException + { + FileInputStream fis = new FileInputStream(file); + byte[] bArray = (byte[]) Array.newInstance(byte.class, (int) file.length()); + Logger.msg(8, "FileStringUtility.file2String() - Reading file '" + file.getAbsolutePath()+"'"); + + fis.read(bArray, 0, (int) file.length()); + fis.close(); + + Logger.msg(9, "FileStringUtility.file2String() - file '" + file.getAbsolutePath() + "' read."); + + return new String(bArray); + } + + /************************************************************************** + * Reads a file and converts it to String + **************************************************************************/ + static public String file2String(String fileName) throws FileNotFoundException, IOException + { + return file2String(new File(fileName)); + } + + /************************************************************************** + * Reads a file and converts it to String + **************************************************************************/ + static public String url2String(java.net.URL location) throws IOException + { + BufferedReader in = new BufferedReader(new InputStreamReader(location.openStream(), "UTF-8")); + StringBuffer strbuf = new StringBuffer(); + String line = in.readLine(); + while (line != null) { + strbuf.append(line).append('\n'); + line = in.readLine(); + } + return strbuf.toString(); + } + + /************************************************************************** + * Reads a file and converts each line to String[] + **************************************************************************/ + static public String[] file2StringArray(File file) throws FileNotFoundException, IOException + { + FileReader fr = new FileReader(file); + BufferedReader buf = new BufferedReader(fr); + Vector lines = new Vector(); + String thisLine = null; + while ((thisLine = buf.readLine()) != null) + lines.addElement(thisLine); + buf.close(); + String[] lineArray = new String[lines.size()]; + for (int i = 0; i < lines.size(); i++) + lineArray[i] = lines.get(i); + return lineArray; + } + + /************************************************************************** + * Reads a file and converts it to String[] + **************************************************************************/ + static public String[] file2StringArray(String fileName) throws FileNotFoundException, IOException + { + return file2StringArray(new File(fileName)); + } + + /************************************************************************** + * Saves a string to a text file + **************************************************************************/ + static public void string2File(File file, String data) throws FileNotFoundException, IOException + { + FileWriter thisFile = new FileWriter(file); + BufferedWriter thisFileBuffer = new BufferedWriter(thisFile); + + Logger.msg(9, "FileStringUtility.string2File() - writing file '" + file.getAbsolutePath()+"'"); + + thisFileBuffer.write(data); + thisFileBuffer.close(); + + Logger.msg(9, "FileStringUtility.string2File() - file '" + file.getAbsolutePath() + "' complete."); + } + + /************************************************************************** + * Saves a string to a text file + **************************************************************************/ + static public void string2File(String fileName, String data) throws FileNotFoundException, IOException + { + string2File(new File(fileName), data); + } + + /************************************************************************** + * checks for existing directory + **************************************************************************/ + static public boolean checkDir(String dirPath) + { + File dir = new File(dirPath); + + if (dir.isFile()) + { + Logger.error("FileStringUtility.checkDir() - '" + dir.getAbsolutePath() + "' is a file."); + return false; + } + else if (!dir.exists()) + { + Logger.msg(9, "FileStringUtility.checkDir() - directory '" + dir.getAbsolutePath() + "' does not exist."); + return false; + } + + return true; + } + + /************************************************************************** + * creating a new directory + **************************************************************************/ + static public boolean createNewDir(String dirPath) + { + File dir = new File(dirPath); + + if (dir.isFile()) + { + Logger.error("FileStringUtility.createNewDir() - '" + dir.getAbsolutePath() + "' is a file."); + return false; + } + else if (dir.exists()) + { + Logger.msg(8, "FileStringUtility.createNewDir() - '" + dir.getAbsolutePath() + "' already exists."); + return false; + } + else + { + if (!dir.mkdirs()) + { + Logger.error("FileStringUtility - Could not create new directory '" + dir.getAbsolutePath() + "'"); + return false; + } + } + return true; + } + + /************************************************************************** + * deleting a existing directory + **************************************************************************/ + static public boolean deleteDir(String dirPath) + { + File dir = new File(dirPath); + + if (!checkDir(dirPath)) + { + Logger.msg(8, "FileStringUtility.deleteDir() - directory '" + dir.getAbsolutePath() + "' does not exist."); + return false; + } + + if (!dir.delete()) + { + //prints the possible reason + if (dir.list().length != 0) + { + Logger.error("FileStringUtility.deleteDir() - cannot delete non-empty directory '" + dir.getAbsolutePath() + "'"); + } + else + { + Logger.error("FileStringUtility.deleteDir() - directory '" + dir.getAbsolutePath() + "' could not be deleted."); + } + return false; + } + + return true; + } + + /************************************************************************** + * deleting a existing directory with its structure + * + * @param dirPath the directory which should be deleted + * @param force if true forces to delete the entry (ie. the dirPath) even if + * it is a file + * @param recursive if true deletes the complete directory structure + **************************************************************************/ + static public boolean deleteDir(String dirPath, boolean force, boolean recursive) + { + File dir = new File(dirPath); + File files[]; + + if (!dir.exists()) + { + Logger.error("FileStringUtility.deleteDir() - directory '" + dir.getAbsolutePath() + "' does not exist."); + return false; + } + + if (dir.isFile()) + { + + if (force) + { //delete the entry even if it is a file + dir.delete(); + return true; + } + else + { + Logger.error("FileStringUtility.deleteDir() - '" + dir.getAbsolutePath() + "' was a file."); + return false; + } + } + + if (recursive) + { + files = dir.listFiles(); + + for (File file : files) + deleteDir(file.getAbsolutePath(), true, true); + } + + return deleteDir(dirPath); + } + + /************************************************************************** + * List all file names in the directory recursively, relative to the + * starting directory. + * + * @param dirPath starting directory + * @param recursive goes into the subdirectories + **************************************************************************/ + static public ArrayList listDir(String dirPath, boolean withDirs, boolean recursive) + { + ArrayList fileNames = new ArrayList(); + File dir = new File(dirPath); + File files[]; + String fileName; + + if (!checkDir(dirPath)) + { + Logger.msg(8, "FileStringUtility.listDir() - directory '" + dir.getAbsolutePath() + "' does not exist."); + return null; + } + + files = dir.listFiles(); + + for (File file : files) { + fileName = file.getName(); + + if (file.isFile()) + { + fileNames.add(dirPath + "/" + fileName); + } + else + { + if (recursive) + fileNames.addAll(listDir(dirPath + "/" + fileName, withDirs, recursive)); + + if (withDirs) + fileNames.add(dirPath + "/" + fileName); + } + } + + return fileNames; + } + + /************************************************************************** + * Open a URL or File as an InputStream + **************************************************************************/ + static public InputStream openTextStream(String source) + { + java.io.InputStream in = null; + java.net.URL url = null; + + // Try to open URL connection first + try + { + try + { + url = new URL(source); + in = url.openStream(); + } + catch (MalformedURLException e) + { + // Try to open plain file, if `configFile' is not a + // URL specification + in = new FileInputStream(source); + } + } + catch (java.io.IOException ex) + { + Logger.error("FileStringUtility.openTextStream() - could not load text stream:" + source); + } + return in; + } + + /************************************************************************** + * Load the contents of the configuration file + **************************************************************************/ + static public java.util.Properties loadConfigFile(String configFile) + { + java.io.BufferedInputStream bin = null; + java.io.InputStream in = openTextStream(configFile); + java.util.Properties props = new java.util.Properties(); + + if (in != null) + { + try + { + bin = new java.io.BufferedInputStream(in); + props.load(bin); + in.close(); + } + catch (IOException ex) + { + Logger.error("FileStringUtility.loadConfigFile() - could not load configuration file '" + configFile+"'"); + } + } + return props; + } + + /************************************************************************** + * Load the contents of the language file + * *************************************************************************/ + static public Hashtable loadLanguageFile(String configFile) + { + try + { + String language = FileStringUtility.file2String(configFile); + Hashtable props = new Hashtable(); + StringTokenizer tok = new StringTokenizer(language, "\n"); + while (tok.hasMoreTokens()) + { + String t = tok.nextToken(); + int sep = t.indexOf("="); + if (sep >0)props.put(t.substring(0,sep),t.substring(sep+1)); + } + return props; + } + catch (Exception e) + { + Logger.error("FileStringUtility.loadLanguageFile() - could not load language file '" + configFile+"'"); + Logger.error(e); + return new Hashtable(); + } + + } + + /************************************************************************** + * Load the contents of the configuration file + **************************************************************************/ + static public void appendConfigFile(java.util.Properties props, String configFile) + { + java.io.BufferedInputStream bin = null; + java.io.InputStream in = openTextStream(configFile); + + if (in != null) + { + try + { + bin = new java.io.BufferedInputStream(in); + props.load(bin); + in.close(); + } + catch (java.io.IOException ex) + { + Logger.error("FileStringUtility.appendConfigFile() - could not append configuration file '" + configFile+"'"); + } + } + } + public static String convert(String init) + { + if (init==null) return null; + return init + .replace('\'', '_') + .replace('\\', '_') + .replace('/', '_') + .replace('\"', '_') + .replace(':', '_') + .replace('*', '_') + .replace('?', '_') + .replace('<', '_') + .replace('>', '_') + .replace('|', '_') + .replace('(', '[') + .replace(')', ']') + .replace(',','_'); } + public static String replaceall(String src,String from,String to) + { + StringBuffer tmp=new StringBuffer(src); + int length = from.length(); + int index = tmp.toString().indexOf(from); + while (index>0) + { + tmp.replace(index,index+length,to); + index = tmp.toString().indexOf(from); + } + return tmp.toString(); + } + public static String toAlphaNum(String source) + { + byte[] sourceb = source.getBytes(); + for (int i=0;i'9'&&sourceb[i]<'A')||(sourceb[i]>'Z'&&sourceb[i]<'_')||sourceb[i]>'z') + sourceb[i]='_'; + } + return new String(sourceb); + + } + +} diff --git a/src/main/java/org/cristalise/kernel/utils/GTimeStampComparator.java b/src/main/java/org/cristalise/kernel/utils/GTimeStampComparator.java new file mode 100644 index 0000000..4a8dd04 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/GTimeStampComparator.java @@ -0,0 +1,46 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.util.Comparator; + +import org.cristalise.kernel.common.GTimeStamp; + + +public class GTimeStampComparator implements Comparator { + + @Override + public int compare(GTimeStamp t0, GTimeStamp t1) { + + int retVal = compareInt(t0.mYear, t1.mYear); + if (retVal == 0) retVal = compareInt(t0.mMonth, t1.mMonth); + if (retVal == 0) retVal = compareInt(t0.mDay, t1.mDay); + if (retVal == 0) retVal = compareInt(t0.mHour-(t0.mTimeOffset/3600), t1.mHour-(t1.mTimeOffset/3600)); + if (retVal == 0) retVal = compareInt(t0.mMinute, t1.mMinute); + if (retVal == 0) retVal = compareInt(t0.mSecond, t1.mSecond); + + return retVal; + } + + private static int compareInt(int i, int j) { + return i-j; + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/KeyValuePair.java b/src/main/java/org/cristalise/kernel/utils/KeyValuePair.java new file mode 100644 index 0000000..67c5fad --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/KeyValuePair.java @@ -0,0 +1,107 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + + +public class KeyValuePair +{ + private String mKey = null; + private Object mValue = null; + private boolean mAbstract = false; + + public KeyValuePair() {} + + public KeyValuePair(String key, Object value, boolean isAbstract) + { + mKey = key; + mValue = value; + mAbstract = isAbstract; + } + + public String getKey() { + return mKey; + } + + public void setKey(String key) { + mKey = key; + } + + public Object getValue() { + return mValue; + } + + public void setValue(Object value) { + mValue = value; + } + + public void setAbstract(boolean isAbstract) { + mAbstract = isAbstract; + } + + public boolean isAbstract() { + return mAbstract; + } + + public String getStringValue() { + if (mValue instanceof String) + return (String)mValue; + else + return null; + } + + public void setStringValue(String value) { + mValue = value; + } + + public Integer getIntegerValue() { + if (mValue instanceof Integer) + return (Integer)mValue; + else + return null; + } + + public void setIntegerValue(Integer value) { + mValue = value; + } + + public Boolean getBooleanValue() { + if (mValue instanceof Boolean) + return (Boolean)mValue; + else + return null; + } + + public void setBooleanValue(Boolean value) { + mValue = value; + } + + public Double getFloatValue() { + if (mValue instanceof Double) + return (Double)mValue; + else + return null; + } + + public void setFloatValue(Double value) { + mValue = value; + } + +} diff --git a/src/main/java/org/cristalise/kernel/utils/Language.java b/src/main/java/org/cristalise/kernel/utils/Language.java new file mode 100644 index 0000000..9f039e8 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/Language.java @@ -0,0 +1,86 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.util.Enumeration; +import java.util.Hashtable; + +/************************************************************************** + * + * @author $Author: sgaspard $ $Date: 2004/09/21 13:17:40 $ + * @version $Revision: 1.9 $ + **************************************************************************/ + +public class Language +{ + public static Hashtable mTableOfTranslation = new Hashtable(); + public static Hashtable mTableOfUntranslated = new Hashtable(); + public static boolean isTranlated=false; + private Hashtable tableOfTranslation = new Hashtable(); + + public static String translate(String english) + { + if (!isTranlated) return english; + String rep = english; + if (rep != null && !rep.equals("")) { + String translated = (String) mTableOfTranslation.get(english); + if (translated != null) return translated; + else + { + mTableOfUntranslated.put(english,""); + try + { + String s = ""; + Enumeration e = mTableOfUntranslated.keys(); + while (e.hasMoreElements()) s =s+"\n"+e.nextElement(); + FileStringUtility.string2File("untranslated.txt",s); + } + catch (Exception ex) + { + Logger.warning("Could not write to preferences file. Preferences have not been updated."); + } + } + + } + return rep; + } + + public Language(String filePath) + { + String languageFile = filePath; + if (languageFile == null || languageFile.length() == 0) + // no language file defined for this process + return; + tableOfTranslation = FileStringUtility.loadLanguageFile(languageFile); + } + public String insTranslate(String english) + { + String rep = english; + if (rep != null && !rep.equals("")) { + String translated = (String) tableOfTranslation.get(english); + if (translated != null) + rep = translated; + } + return rep; + } + + +} diff --git a/src/main/java/org/cristalise/kernel/utils/LocalObjectLoader.java b/src/main/java/org/cristalise/kernel/utils/LocalObjectLoader.java new file mode 100644 index 0000000..416d0a5 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/LocalObjectLoader.java @@ -0,0 +1,111 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.util.Iterator; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.common.PersistencyException; +import org.cristalise.kernel.entity.proxy.ItemProxy; +import org.cristalise.kernel.lifecycle.ActivityDef; +import org.cristalise.kernel.lifecycle.instance.stateMachine.StateMachine; +import org.cristalise.kernel.lookup.DomainPath; +import org.cristalise.kernel.lookup.Path; +import org.cristalise.kernel.persistency.ClusterStorage; +import org.cristalise.kernel.persistency.outcome.Schema; +import org.cristalise.kernel.persistency.outcome.Viewpoint; +import org.cristalise.kernel.process.Gateway; + + +public class LocalObjectLoader { + private static ActDefCache actCache = new ActDefCache(); + private static StateMachineCache smCache = new StateMachineCache(); + + static public ItemProxy loadLocalObjectDef(String root, String name) + throws ObjectNotFoundException + { + DomainPath defRoot = new DomainPath(root); + Iterator e = Gateway.getLookup().search(defRoot, name); + if (e.hasNext()) { + DomainPath defPath = (DomainPath)e.next(); + if (e.hasNext()) throw new ObjectNotFoundException("Too many matches for "+name+" in "+root); + return Gateway.getProxyManager().getProxy(defPath); + } + else { + throw new ObjectNotFoundException("No match for "+name+" in "+root); + } + + } + + static public String getScript(String scriptName, int scriptVersion) throws ObjectNotFoundException { + Logger.msg(5, "Loading script "+scriptName+" v"+scriptVersion); + try { + ItemProxy script = loadLocalObjectDef("/desc/Script/", scriptName); + Viewpoint scriptView = (Viewpoint)script.getObject(ClusterStorage.VIEWPOINT + "/Script/" + scriptVersion); + return scriptView.getOutcome().getData(); + } catch (PersistencyException ex) { + Logger.error(ex); + throw new ObjectNotFoundException("Error loading script " + scriptName + " version " + scriptVersion); + } + + } + + static public Schema getSchema(String schemaName, int schemaVersion) throws ObjectNotFoundException { + Logger.msg(5, "Loading schema "+schemaName+" v"+schemaVersion); + + String docType = schemaName; + int docVersion = schemaVersion; + String schemaData; + + // don't bother if this is the Schema schema - for bootstrap esp. + if (schemaName.equals("Schema") && schemaVersion == 0) + return new Schema(docType, docVersion, ""); + + ItemProxy schema = loadLocalObjectDef("/desc/OutcomeDesc/", schemaName); + Viewpoint schemaView = (Viewpoint)schema.getObject(ClusterStorage.VIEWPOINT + "/Schema/" + schemaVersion); + try { + schemaData = schemaView.getOutcome().getData(); + } catch (PersistencyException ex) { + Logger.error(ex); + throw new ObjectNotFoundException("Problem loading schema "+schemaName+" v"+schemaVersion+": "+ex.getMessage()); + } + return new Schema(docType, docVersion, schemaData); + } + + /** + * Retrieves a named version of activity def from the database + * + * @param actName - activity name + * @param version - named version (String) + * @return ActivityDef + * @throws ObjectNotFoundException - When activity or version does not exist + */ + static public ActivityDef getActDef(String actName, int actVersion) throws ObjectNotFoundException, InvalidDataException { + Logger.msg(5, "Loading activity def "+actName+" v"+actVersion); + return actCache.get(actName, actVersion); + } + + static public StateMachine getStateMachine(String smName, int smVersion) throws ObjectNotFoundException, InvalidDataException { + Logger.msg(5, "Loading activity def "+smName+" v"+smVersion); + return smCache.get(smName, smVersion); + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/Logger.java b/src/main/java/org/cristalise/kernel/utils/Logger.java new file mode 100644 index 0000000..244cf4c --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/Logger.java @@ -0,0 +1,207 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.Iterator; + +import org.cristalise.kernel.process.AbstractMain; +import org.cristalise.kernel.process.Gateway; +import org.cristalise.kernel.scripting.ScriptConsole; +import org.cristalise.kernel.utils.server.SimpleTCPIPServer; + +/** + *
- message string should always contain the class name and the method name: Logger.msg(1,"ItemFact::createDir() - LifeCycle DB created"); - use meaningfull abbreviation and also use the dash to separate the 'header' from the message! - each method should start with this 'method signature' debug: Logger.msg(1,"ItemFact::createDir() - path:" + path);
+*
+ */ +public class Logger +{ + /** + * logging level 0 (only error & warning) => no logging ; 9 => maximum logging + * add ten to output time before each message + */ + private static int mHighestLogLevel = 0; + private static long startTime = System.currentTimeMillis(); + private static HashMap logStreams = new HashMap(); + static protected SimpleTCPIPServer mConsole = null; + + static private void printMessage(String message, int msgLogLevel) + { + synchronized(logStreams) { + for (Iterator iter = logStreams.keySet().iterator(); iter.hasNext();) { + PrintStream element = iter.next(); + int logLevel = logStreams.get(element); + + if ( (logLevel > 9 && logLevel - 10 < msgLogLevel) || + (msgLogLevel > 9 && logLevel < msgLogLevel - 10) || + (logLevel < 10 && msgLogLevel < 10 && logLevel < msgLogLevel) ) + continue; + + if (logLevel > 9 || msgLogLevel > 9) { + message = reportTime() + " - " + message; + } + + try { + element.println(message); + } catch (Exception ex) { + iter.remove(); + } + } + } + } + + static private String reportTime() { + long now = System.currentTimeMillis(); + Timestamp ts = new Timestamp(now); + double since = (now - startTime) / 1000.0; + return ts.toString() + " ("+since+"s)"; + } + + static private void printMessage(Throwable ex) { + StringWriter msgString = new StringWriter(); + PrintWriter msg = new PrintWriter(msgString); + msg.print(ex instanceof Exception ? "EXCEPTION:" : "JVM ERROR:"); + ex.printStackTrace(msg); + printMessage(msgString.toString(), 0); + } + + static public boolean doLog(int logLevel) + { + if (logLevel > 9) logLevel -= 10; + return mHighestLogLevel >= logLevel; + } + /** + * Use this only for temporary messages while developing/debugging. When the code is stable, change calls to debug to + * message/warning/error with an appropriate log level. Is is marked deprecated to highlight stray calls. This makes + * it easier to manage debug calls in the source. + * + * @param msg - + * the string to write to the console, or log file if specified in cmd line + * @deprecated + */ + @Deprecated + static public void debug(String msg) + { + msg("DEBUG : " + msg); + } + static public void debug(int logLevel, String msg) + { + msg(logLevel, "DEBUG : " + msg); + } + /** + * Use Logger.message to report information that will be useful for debugging a release + * + * @param level - + * log level of this message. If the current log level has been on the cmd line to be less that this number, the log message + * will not be displayed + * @param msg - + * the string to write to the console, or log file if specified in cmd line + */ + static public void msg(int level, String msg) + { + printMessage(msg, level); + } + static public void msg(String msg) + { + printMessage(msg, 0); + } + static public void error(String msg) + { + printMessage("ERROR : " + msg, 0); + } + static public void error(Throwable ex) + { + printMessage(ex); + } + static public void warning(String msg) + { + printMessage("WARNING: " + msg, 0); + } + static public void die(String msg) + { + printMessage("FATAL : " + msg, 0); + AbstractMain.shutdown(1); + } + /** + * @param console + */ + public static void addLogStream(PrintStream console, int logLevel) { + try { + console.println("***********************************************************"); + console.println(" CRISTAL log started at level "+logLevel+" @"+new Timestamp(System.currentTimeMillis()).toString()); + console.println("***********************************************************"); + } catch (Exception ex) { + System.out.println("Exception accessing log stream"); + ex.printStackTrace(); + } + + synchronized(logStreams) { + logStreams.put(console, logLevel); + if ((logLevel>10?logLevel-10:logLevel) > mHighestLogLevel) mHighestLogLevel = logLevel; + } + + } + /** + * @param console + */ + public static void removeLogStream(PrintStream console) { + synchronized(logStreams) { + Integer logIntObj = logStreams.get(console); + if (logIntObj == null) return; // not registered + int logLevel = (logIntObj).intValue(); + logStreams.remove(console); + + // recalculate lowest log level + if (logLevel == mHighestLogLevel || (logLevel > 9 && logLevel-10 == mHighestLogLevel)) { + mHighestLogLevel = 0; + for (Integer element : logStreams.values()) { + int thisLogLevel = element>9?element-10:element; + if (thisLogLevel > mHighestLogLevel) + mHighestLogLevel = thisLogLevel; + } + } + } + } + + static public void initConsole(String id) + { + int port = Gateway.getProperties().getInt(id+".Console.port", 0); + if (port == 0) + Logger.msg("No port defined for "+id+" console. Using any port."); + + mConsole = new SimpleTCPIPServer(port, ScriptConsole.class, 5); + mConsole.startListening(); + Gateway.getProperties().setProperty(id+".Console.port", String.valueOf(mConsole.getPort())); + } + + static public int getConsolePort() { + return mConsole.getPort(); + } + + static public void closeConsole() + { + if (mConsole != null) + mConsole.stopListening(); + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/ObjectProperties.java b/src/main/java/org/cristalise/kernel/utils/ObjectProperties.java new file mode 100644 index 0000000..31ff57c --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/ObjectProperties.java @@ -0,0 +1,215 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Properties; +import java.util.StringTokenizer; + +public class ObjectProperties extends Properties { + + public ObjectProperties() { + } + + public ObjectProperties(Properties defaults) { + super(defaults); + } + + public String getString(String propName) { + return getString(propName, null); + } + + public String getString(String propName, String defaultValue) { + String value = super.getProperty(propName, defaultValue); + if (value!=null) value = value.trim(); + return value; + } + + /** + * ogattaz proposal + * + * @param propName + * the name of the property + * @return the object value of the property. Returns null if the property + * doesn't exist or if the properties of the gateway is null + */ + public Object getObject(String propName) { + return getObject(propName, null); + } + + /** + * ogattaz proposal + * + * @param aPropertyName + * the name of the property + * @param defaultValue + * the default value. + * @return the object value of the property. Returns the default value if the property + * doesn't exist or if the properties of the gateway is null. + * @return + */ + public Object getObject(String propName, + Object defaultValue) { + + Object wValue = get(propName); + if (wValue == null) { + return defaultValue; + } + return wValue; + } + + /** + * ogattaz proposal + * + * @param propName + * the name of the paroperty + * @return the boolean value of the property. Returns false if the property + * doesn't exist or if the value is not a String or a Boolean + * instance + */ + public boolean getBoolean(String aPropertyName) { + return getBoolean(aPropertyName, Boolean.FALSE); + } + + /** + * ogattaz proposal + * + * @param propName + * the name of the parameter stored in the clc file + * @param defaultValue + * the default value + * @return the boolean value of the property. Returns the default value if + * the property doesn't exist or if the value is not a String or a + * Boolean instance + */ + public boolean getBoolean(String aPropertyName, + boolean defaultValue) { + + Object wValue = getObject(aPropertyName, Boolean.valueOf(defaultValue)); + if (wValue instanceof Boolean) { + return ((Boolean) wValue).booleanValue(); + } + if (wValue instanceof String) { + return Boolean.parseBoolean((String) wValue); + } + Logger.error("getBoolean(): unable to retrieve a int value for ["+aPropertyName+"]. Returning default value ["+defaultValue+"]. object found="+wValue); + + return defaultValue; + } + + /** + * ogattaz proposal + * + * @param propName + * the name of the property + * @return the int value of the property. Returns -1 if the property doesn't + * exist or if the value is not a String or an Integer instance + */ + public int getInt(String aPropertyName) { + return getInt(aPropertyName, -1); + } + + /** + * ogattaz proposal + * + * @param propName + * the name of the property + * @param defaultValue + * the default value + * @return the int value of the property. Returns the default vakue if the + * property doesn't exist or if the value is not a String or an + * Integer instance + */ + public int getInt(String aPropertyName, int defaultValue) { + + Object wValue = getObject(aPropertyName, Integer.valueOf(defaultValue)); + if (wValue instanceof Integer) { + return ((Integer) wValue).intValue(); + } + if (wValue instanceof String) { + try { + return Integer.parseInt((String) wValue); + } catch (NumberFormatException ex) { } + } + Logger.error("getInt(): unable to retrieve a int value for ["+aPropertyName+"]. Returning default value ["+defaultValue+"]. object found="+wValue); + return defaultValue; + } + + /** + * Allow setting of properties as Objects + * + * @param aPropertyName + * the name of the property + * @param aPropertyValue + */ + public void setProperty(String aPropertyName, Object aPropertyValue) { + put(aPropertyName, aPropertyValue); + } + + public void dumpProps(int logLevel) { + Logger.msg(logLevel, "Properties:"); + for (Enumeration e = propertyNames(); e.hasMoreElements();) { + String name = (String) e.nextElement(); + Object value = getObject(name); + if (value == null) + Logger.msg(" "+name+": null"); + else + Logger.msg(" "+name+" ("+getObject(name).getClass().getSimpleName()+"): '"+getObject(name).toString()+"'"); + } + } + + public Object getInstance(String propName, Object defaultVal) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + Object prop = getObject(propName, defaultVal); + if (prop == null || prop.equals("")) + throw new InstantiationException("Property '"+propName+"' was not defined. Cannot instantiate."); + if (prop instanceof String) + return Class.forName(((String)prop).trim()).newInstance(); + return prop; + } + + public Object getInstance(String propName) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + return getInstance(propName, null); + } + + public ArrayList getInstances(String propName, Object defaultVal) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + Object val = getObject(propName, defaultVal); + if (val == null) return null; + if (val instanceof ArrayList) + return (ArrayList)val; + else if (val instanceof String) { + ArrayList retArr = new ArrayList(); + StringTokenizer tok = new StringTokenizer((String)val, ","); + while (tok.hasMoreTokens()) + retArr.add(getInstance(tok.nextToken())); + return retArr; + } + else { + ArrayList retArr = new ArrayList(); + retArr.add(val); + return retArr; + } + } + + public ArrayList getInstances(String propName) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + return getInstances(propName, null); + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/SoftCache.java b/src/main/java/org/cristalise/kernel/utils/SoftCache.java new file mode 100644 index 0000000..7444dcf --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/SoftCache.java @@ -0,0 +1,139 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +/******************************************************************************* + * SoftReferences are reaped if no strong references are left and the vm is + * running out of memory. Most caches in the kernel use this. + * + * $Revision: 1.5 $ $Date: 2004/10/29 13:29:09 $ + ******************************************************************************/ +public class SoftCache extends AbstractMap { + + private final Map> hash = new HashMap>(); + private final int minSize; + private final LinkedList hardCache = new LinkedList(); + private final ReferenceQueue queue = new ReferenceQueue(); + + public SoftCache() { + this(0); + } + + public SoftCache(int minSize) { + this.minSize = minSize; + } + + @Override + public V get(Object key) { + V result = null; + SoftValue soft_ref = hash.get(key); + if (soft_ref != null) { + result = soft_ref.get(); + if (result == null) + hash.remove(key); + else + if (minSize > 0) { // add to hard cache so it's not reaped for a while + synchronized(hardCache) { + hardCache.addFirst(result); + if (hardCache.size() > minSize) // trim last one off + hardCache.removeLast(); + } + } + } + return result; + } + + @Override + public V put(K key, V value) { + processQueue(); + if (minSize > 0) { + synchronized(hardCache) { + hardCache.addFirst(value); + if (hardCache.size() > minSize) + hardCache.removeLast(); + } + } + hash.put(key, new SoftValue(key, value, queue)); + return value; + } + + @Override + public V remove(Object key) { + processQueue(); + if (hash.containsKey(key)) return hash.remove(key).get(); + return null; + } + + @Override + public void clear() { + synchronized(hardCache) { + hardCache.clear(); + } + while(queue.poll()!=null); + hash.clear(); + } + + @Override + public int size() { + processQueue(); + return hash.size(); + } + + @Override + public Set keySet() { + processQueue(); + return hash.keySet(); + } + + @Override + public Set> entrySet() { + // Would have to create another Map to do this - too expensive + // Throwing runtime expensive is dangerous, but better than nulls + throw new UnsupportedOperationException(); + } + + private static class SoftValue extends SoftReference { + private final Object key; + private SoftValue(Object key, V value, ReferenceQueue q) { + super(value, q); + this.key = key; + } + } + + /** + * Look for values that have been reaped, and remove their keys from the cache + */ + private void processQueue() { + SoftValue sv; + while ((sv = (SoftValue) queue.poll()) != null) { + hash.remove(sv.key); + } + } + +} diff --git a/src/main/java/org/cristalise/kernel/utils/StateMachineCache.java b/src/main/java/org/cristalise/kernel/utils/StateMachineCache.java new file mode 100644 index 0000000..5aa87b9 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/StateMachineCache.java @@ -0,0 +1,67 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +/** + * + */ +package org.cristalise.kernel.utils; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.common.PersistencyException; +import org.cristalise.kernel.entity.proxy.ItemProxy; +import org.cristalise.kernel.lifecycle.instance.stateMachine.StateMachine; +import org.cristalise.kernel.persistency.ClusterStorage; +import org.cristalise.kernel.persistency.outcome.Viewpoint; +import org.cristalise.kernel.process.Gateway; + + +public class StateMachineCache extends DescriptionObjectCache { + + + @Override + public String getDefRoot() { + return "/desc/StateMachine"; + } + + @Override + public StateMachine loadObject(String name, int version, ItemProxy proxy) throws ObjectNotFoundException, InvalidDataException { + StateMachine thisStateMachine; + Viewpoint smView = (Viewpoint)proxy.getObject(ClusterStorage.VIEWPOINT + "/StateMachine/" + version); + String marshalledSM; + try { + marshalledSM = smView.getOutcome().getData(); + } catch (PersistencyException ex) { + Logger.error(ex); + throw new ObjectNotFoundException("Problem loading State Machine "+name+" v"+version+": "+ex.getMessage()); + } + try { + thisStateMachine = (StateMachine)Gateway.getMarshaller().unmarshall(marshalledSM); + thisStateMachine.validate(); + } catch (Exception ex) { + Logger.error(ex); + throw new InvalidDataException("Could not unmarshall State Machine '"+name+"' v"+version+": "+ex.getMessage()); + } + thisStateMachine.setName(name); + thisStateMachine.setVersion(version); + return thisStateMachine; + } + +} \ No newline at end of file diff --git a/src/main/java/org/cristalise/kernel/utils/TransientCache.java b/src/main/java/org/cristalise/kernel/utils/TransientCache.java new file mode 100644 index 0000000..4b13e0e --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/TransientCache.java @@ -0,0 +1,149 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; +import java.lang.ref.Reference; +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +/************************************************************************** + * TransientCache - Uses transient references to allow unused entries to be + * reaped by the java garbage collector. + * + * $Revision: 1.1 $ + * $Date: 2004/04/20 09:37:02 $ + * + * Copyright (C) 2003 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ +public abstract class TransientCache extends AbstractMap { + + private Map> map = new Hashtable>(); + + @Override + public synchronized Set> entrySet() { + Map newMap = new Hashtable(); + Iterator>> iter = map.entrySet().iterator(); + while (iter.hasNext()) { + Entry> me = iter.next(); + Reference ref = me.getValue(); + V o = ref.get(); + if (o == null) { + // Delete cleared reference + iter.remove(); + } else { + // Copy out interior object + newMap.put(me.getKey(), o); + } + } + // Return set of interior objects + return newMap.entrySet(); + } + + @Override + public synchronized V put(K key, V value) { + Reference ref = makeReference(value); + ref = map.put(key, ref); + if (ref != null) + return (ref.get()); + return null; + } + + public abstract Reference makeReference(Object value); + + @Override + public V remove(Object key) { + Iterator>> i = map.entrySet().iterator(); + Entry> correctEntry = null; + if (key == null) { + while (correctEntry == null && i.hasNext()) { + Entry> e = i.next(); + if (e.getKey() == null) + correctEntry = e; + } + } else { + while (correctEntry == null && i.hasNext()) { + Entry> e = i.next(); + if (key.equals(e.getKey())) + correctEntry = e; + } + } + V oldValue = null; + if (correctEntry != null) { + Reference correctReference = correctEntry.getValue(); + oldValue = correctReference.get(); + i.remove(); + } + return oldValue; + } + /** + * + */ + @Override + public void clear() { + map.entrySet().clear(); + } + + private transient Set keySet = null; + + @Override + public Set keySet() { + if (keySet == null) { + keySet = new AbstractSet() { + @Override + public Iterator iterator() { + return new Iterator() { + private Iterator>> i = map.entrySet().iterator(); + + @Override + public boolean hasNext() { + return i.hasNext(); + } + + @Override + public K next() { + return i.next().getKey(); + } + + @Override + public void remove() { + i.remove(); + } + }; + } + + @Override + public int size() { + return TransientCache.this.size(); + } + + @Override + public boolean contains(Object k) { + return TransientCache.this.containsKey(k); + } + }; + } + return keySet; + } + +} diff --git a/src/main/java/org/cristalise/kernel/utils/WeakCache.java b/src/main/java/org/cristalise/kernel/utils/WeakCache.java new file mode 100644 index 0000000..3a37031 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/WeakCache.java @@ -0,0 +1,154 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +/******************************************************************************* + * WeakReferences are reaped if no strong references are left next time the gc has a chance. + * The ClusterStorageManager caches can optionally use this one, for high volume imports etc + * + * $Revision: 1.5 $ $Date: 2004/10/29 13:29:09 $ + ******************************************************************************/ +public class WeakCache extends AbstractMap { + + private final Map> hash = new HashMap>(); + private final int minSize; + private final LinkedList hardCache = new LinkedList(); + private final ReferenceQueue queue = new ReferenceQueue(); + + public WeakCache() { + this(0); + } + + public WeakCache(int minSize) { + this.minSize = minSize; + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#get(java.lang.Object) + */ + @Override + public V get(Object key) { + V result = null; + WeakValue weak_ref = hash.get(key); + if (weak_ref != null) { + result = weak_ref.get(); + if (result == null) + hash.remove(key); + else + if (minSize > 0) { // add to hard cache so it's not reaped for a while + hardCache.addFirst(result); + if (hardCache.size() > minSize) // trim last one off + hardCache.removeLast(); + } + } + return result; + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#put(K, V) + */ + @Override + public V put(K key, V value) { + processQueue(); + if (minSize > 0) { + hardCache.addFirst(value); + if (hardCache.size() > minSize) + hardCache.removeLast(); + } + hash.put(key, new WeakValue(key, value, queue)); + return value; + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#remove(java.lang.Object) + */ + @Override + public V remove(Object key) { + processQueue(); + if (hash.containsKey(key)) return hash.remove(key).get(); + return null; + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#clear() + */ + @Override + public void clear() { + hardCache.clear(); + while(queue.poll()!=null); + hash.clear(); + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#size() + */ + @Override + public int size() { + processQueue(); + return hash.size(); + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#keySet() + */ + @Override + public Set keySet() { + processQueue(); + return hash.keySet(); + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.utils.NonStrongRefCache#entrySet() + */ + @Override + public Set> entrySet() { + // Would have to create another Map to do this - too expensive + // Throwing runtime expensive is dangerous, but better than nulls + throw new UnsupportedOperationException(); + } + + private static class WeakValue extends WeakReference { + private final Object key; + private WeakValue(Object key, V value, ReferenceQueue q) { + super(value, q); + this.key = key; + } + } + + /** + * Look for values that have been reaped, and remove their keys from the cache + */ + private void processQueue() { + WeakValue sv; + while ((sv = (WeakValue) queue.poll()) != null) { + hash.remove(sv.key); + } + } + +} diff --git a/src/main/java/org/cristalise/kernel/utils/XmlElementParser.java b/src/main/java/org/cristalise/kernel/utils/XmlElementParser.java new file mode 100644 index 0000000..a722410 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/XmlElementParser.java @@ -0,0 +1,125 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils; + +import java.io.StringReader; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +public class XmlElementParser { + public static String[] parse(String data, String xpath) { + Vector returnData = new Vector(); + String[] returnArray; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + Logger.error(e); + throw new RuntimeException("Could not create XML Document Builder"); + } + StringReader is = new StringReader(data); + Document doc; + try { + doc = builder.parse(new InputSource(is)); + } catch (Exception e) { + Logger.error(e); + throw new RuntimeException("Parser malfunction"); + } + StringTokenizer pathTokens = new StringTokenizer(xpath, "/"); + int taille = pathTokens.countTokens(); + String[] pathElements = new String[taille]; + int i = taille; + while (pathTokens.hasMoreElements()) + pathElements[--i] = pathTokens.nextToken(); + + if (Logger.doLog(6)) { + Logger.msg(6, "Path elements:"); + for (String pathElement : pathElements) + Logger.debug(6, pathElement); + } + + Logger.msg(6, "Looking for attribute " + pathElements[0] + " in " + + pathElements[1]); + NodeList nl = doc.getElementsByTagName(pathElements[1]); + for (int j = 0; j < nl.getLength(); j++) { + Logger.msg(6, "Found one"); + Element e = (Element) nl.item(j); + boolean match = true; + Node child = e; + for (int k = 2; k < taille && match; k++) { + Logger.msg(6, "Checking parent " + pathElements[k]); + child = child.getParentNode(); + if (!child.getNodeName().equals(pathElements[k])) { + Logger.msg(6, "No match for " + child.getNodeName()); + match = false; + } else + Logger.msg(6, "Match"); + } + if (match && e.hasAttribute(pathElements[0])) { + Logger.msg( + 6, + "Matching Attribute " + pathElements[0] + "=" + + e.getAttribute(pathElements[0])); + returnData.add(e.getAttribute(pathElements[0])); + } + } + + Logger.msg(6, "Looking for element " + pathElements[0]); + nl = doc.getElementsByTagName(pathElements[0]); + for (int j = 0; j < nl.getLength(); j++) { + Logger.msg(6, "Found one"); + Element e = (Element) nl.item(j); + boolean match = true; + Node child = e; + for (int k = 1; k < taille && match; k++) { + Logger.msg(6, "Checking parent " + pathElements[k]); + child = child.getParentNode(); + if (!child.getNodeName().equals(pathElements[k])) { + Logger.msg(6, "No match for " + child.getNodeName()); + match = false; + } else + Logger.msg(6, "Match"); + } + if (match) { + String s = e.getFirstChild().getNodeValue(); + Logger.msg(6, "Found Element " + pathElements[0] + "=" + s); + if (s != null) + returnData.add(s); + } + } + Logger.msg(3, returnData.size() + " values found for " + xpath); + returnArray = new String[returnData.size()]; + for (int j = 0; j < returnArray.length; j++) + returnArray[j] = returnData.get(j); + return returnArray; + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/server/SimpleTCPIPServer.java b/src/main/java/org/cristalise/kernel/utils/server/SimpleTCPIPServer.java new file mode 100644 index 0000000..16beffe --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/server/SimpleTCPIPServer.java @@ -0,0 +1,130 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils.server; + +import java.io.InterruptedIOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +import org.cristalise.kernel.utils.Logger; + + + +public class SimpleTCPIPServer implements Runnable +{ + int port = 0; + int maxConn = 10; + Thread listener = null; + Class handlerClass = null; + ServerSocket serverSocket = null; + boolean keepListening = true; + ArrayList currentHandlers = new ArrayList(); + static short noServers = 0; + + public SimpleTCPIPServer(int port, Class handlerClass, int maxConnections) + { + this.port = port; + this.handlerClass = handlerClass; + this.maxConn = maxConnections; + noServers++; + } + + public void startListening() + { + if(listener != null) return; + keepListening = true; + + listener = new Thread(this); + listener.start(); + } + + public void stopListening() + { + Logger.msg("SimpleTCPIPServer: Closing server for " + handlerClass.getName() +" on port "+ port); + keepListening = false; + for (SocketHandler thisHandler : currentHandlers) { + thisHandler.shutdown(); + } + } + + @Override + public void run() + { + Thread.currentThread().setName("TCP/IP Server for "+handlerClass.getName()); + Socket connectionSocket = null; + + try { + serverSocket = new ServerSocket(port); + if (port == 0) + port = serverSocket.getLocalPort(); + Logger.msg("SimpleTCPIPServer: Created server for " + handlerClass.getName()+" on port "+port); + serverSocket.setSoTimeout(500); + SocketHandler freeHandler = null; + while(keepListening) { + if (freeHandler == null || freeHandler.isBusy()) { + ListIterator i = currentHandlers.listIterator(); + try { + do { + freeHandler = i.next(); + } while (freeHandler.isBusy()); + } catch (NoSuchElementException e) { + // create new one + if (currentHandlers.size() < maxConn) { + freeHandler = (SocketHandler)handlerClass.newInstance(); + currentHandlers.add(freeHandler); + } + else { // max handlers are created. wait for a while, then look again + Logger.warning("No free handlers left for "+handlerClass.getName()+" on port "+ port + "!"); + Thread.sleep(2000); + continue; + } + } + } + try { + connectionSocket = serverSocket.accept(); + if (keepListening) { + Logger.msg("SimpleTCPIPServer: Connection to "+freeHandler.getName()+" from "+ + connectionSocket.getInetAddress()); + freeHandler.setSocket(connectionSocket); + new Thread(freeHandler).start(); + } + } catch (InterruptedIOException ex1) { }// timeout just to check if we've been told to die + + } + serverSocket.close(); + Logger.msg("SimpleTCPIPServer: Server closed for " + handlerClass.getName() +" on port "+ port); + } catch(Exception ex) { + Logger.error(ex); + Logger.error("SimpleTCPIPServer.run(): Fatal Error. Listener for '"+handlerClass.getName()+"' will stop."); + listener = null; --noServers; + return; + } + listener = null; + Logger.msg("SimpleTCPIPServer - Servers still running: "+--noServers); + } + + public int getPort() { + return port; + } +} diff --git a/src/main/java/org/cristalise/kernel/utils/server/SocketHandler.java b/src/main/java/org/cristalise/kernel/utils/server/SocketHandler.java new file mode 100644 index 0000000..457fc52 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/utils/server/SocketHandler.java @@ -0,0 +1,35 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.utils.server; + +import java.net.Socket; + +public interface SocketHandler extends Runnable { + + public String getName(); + + public boolean isBusy(); + + public void setSocket(Socket newSocket); + + public void shutdown(); +} + -- cgit v1.2.3