diff options
Diffstat (limited to 'src/main/java/com/c2kernel/utils')
19 files changed, 2149 insertions, 0 deletions
diff --git a/src/main/java/com/c2kernel/utils/ActDefCache.java b/src/main/java/com/c2kernel/utils/ActDefCache.java new file mode 100644 index 0000000..0c9fea1 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/ActDefCache.java @@ -0,0 +1,98 @@ +/**
+ *
+ */
+package com.c2kernel.utils;
+
+import com.c2kernel.common.InvalidDataException;
+import com.c2kernel.common.ObjectNotFoundException;
+import com.c2kernel.entity.proxy.EntityProxyObserver;
+import com.c2kernel.entity.proxy.ItemProxy;
+import com.c2kernel.entity.proxy.MemberSubscription;
+import com.c2kernel.lifecycle.ActivityDef;
+import com.c2kernel.persistency.ClusterStorage;
+import com.c2kernel.persistency.ClusterStorageException;
+import com.c2kernel.persistency.outcome.Viewpoint;
+
+public class ActDefCache {
+
+ SoftCache<String, ActCacheEntry> actCache = new SoftCache<String, ActCacheEntry>();
+
+ public ActivityDef get(String actName, String actVersion) throws ObjectNotFoundException, InvalidDataException {
+ ActivityDef thisActDef;
+ synchronized(actCache) {
+ ActCacheEntry thisActDefEntry = actCache.get(actName+"_"+actVersion);
+ if (thisActDefEntry == null) {
+ Logger.msg(6, actName+" v"+actVersion+" not found in cache. Retrieving.");
+ ItemProxy actDefItem = LocalObjectLoader.loadLocalObjectDef("/desc/ActivityDesc/", actName);
+ String actType = actDefItem.getProperty("Complexity");
+ Viewpoint actView = (Viewpoint)actDefItem.getObject(ClusterStorage.VIEWPOINT + "/" + actType + "ActivityDef/" + actVersion);
+ String marshalledAct;
+ try {
+ marshalledAct = actView.getOutcome().getData();
+ } catch (ClusterStorageException ex) {
+ Logger.error(ex);
+ throw new ObjectNotFoundException("Problem loading "+actName+" v"+actVersion+": "+ex.getMessage(), "");
+ }
+ try {
+ thisActDef = (ActivityDef)CastorXMLUtility.unmarshall(marshalledAct);
+ } catch (Exception ex) {
+ Logger.error(ex);
+ throw new InvalidDataException("Could not unmarshall '"+actName+"' v"+actVersion+": "+ex.getMessage(), "");
+ }
+ thisActDef.setName(actName);
+ thisActDef.setVersion(actVersion);
+ actCache.put(actName+"_"+actVersion, new ActCacheEntry(thisActDef, actDefItem, this));
+ }
+ else {
+ Logger.msg(6, actName+" v"+actVersion+" found in cache.");
+ thisActDef = thisActDefEntry.actDef;
+ }
+ }
+ return thisActDef;
+ }
+
+ public void removeAct(String id) {
+ synchronized(actCache) {
+ if (actCache.keySet().contains(id)) {
+ Logger.msg(7, "ActDefCache: Removing activity def "+id+" from cache");
+ actCache.remove(id);
+ }
+ }
+ }
+
+ public class ActCacheEntry implements EntityProxyObserver<Viewpoint> {
+ public String id;
+ public ItemProxy actProxy;
+ public ActivityDef actDef;
+ public ActDefCache parent;
+ public ActCacheEntry(ActivityDef actDef, ItemProxy actProxy, ActDefCache parent) {
+ this.id = actDef.getName()+"_"+actDef.getVersion();
+ this.actDef = actDef;
+ this.parent = parent;
+ this.actProxy = actProxy;
+ actProxy.subscribe(new MemberSubscription<Viewpoint>(this, ClusterStorage.VIEWPOINT, false));
+ }
+ @Override
+ public void finalize() {
+ parent.removeAct(id);
+ actProxy.unsubscribe(this);
+ }
+ @Override
+ public void add(Viewpoint contents) {
+ parent.removeAct(id);
+ }
+
+ @Override
+ public void remove(String id) {
+ parent.removeAct(id);
+ }
+
+ @Override
+ public String toString() {
+ return "ActDef cache entry: "+id;
+ }
+ @Override
+ public void control(String control, String msg) {
+ }
+ }
+}
\ No newline at end of file diff --git a/src/main/java/com/c2kernel/utils/CastorArrayList.java b/src/main/java/com/c2kernel/utils/CastorArrayList.java new file mode 100644 index 0000000..ea9a090 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/CastorArrayList.java @@ -0,0 +1,30 @@ +package com.c2kernel.utils;
+
+import java.io.Serializable;
+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<T> implements Serializable {
+ public ArrayList<T> list;
+
+ public CastorArrayList() {
+ super();
+ list = new ArrayList<T>();
+ }
+
+ public CastorArrayList(ArrayList<T> list) {
+ this();
+ this.list = list;
+ }
+}
diff --git a/src/main/java/com/c2kernel/utils/CastorHashMap.java b/src/main/java/com/c2kernel/utils/CastorHashMap.java new file mode 100644 index 0000000..25e5ab4 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/CastorHashMap.java @@ -0,0 +1,54 @@ +package com.c2kernel.utils;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+
+// This subclass of hashtable can be marshalled
+// and unmarshalled with Castor
+public class CastorHashMap extends HashMap<String,Object>
+{
+ public CastorHashMap()
+ {
+ clear();
+ }
+
+ public KeyValuePair[] getKeyValuePairs()
+ {
+ int numKeys = size();
+
+ KeyValuePair[] keyValuePairs = new KeyValuePair[numKeys];
+ Iterator<String> keyIter = keySet().iterator();
+ int i = 0;
+
+ for(i=0; i<numKeys; i++)
+ if (keyIter.hasNext())
+ {
+ String tmp = keyIter.next();
+ keyValuePairs[i] = new KeyValuePair(tmp,get(tmp));
+ }
+
+ return keyValuePairs;
+ }
+
+
+ public void setKeyValuePairs(KeyValuePair[] keyValuePairs)
+ {
+ int i = 0;
+
+ // Clears this hashtable so that it contains no keys
+ clear();
+
+ // Put each key value pair into this hashtable
+ for(i=0; i<keyValuePairs.length; i++)
+ {
+ setKeyValuePair(keyValuePairs[i]);
+ }
+ }
+
+ public void setKeyValuePair(KeyValuePair keyValuePair)
+ {
+ put(keyValuePair.getKey(), keyValuePair.getValue());
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/utils/CastorXMLUtility.java b/src/main/java/com/c2kernel/utils/CastorXMLUtility.java new file mode 100644 index 0000000..4dca391 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/CastorXMLUtility.java @@ -0,0 +1,126 @@ +package com.c2kernel.utils;
+
+//Java
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+
+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 com.c2kernel.common.InvalidDataException;
+import com.c2kernel.persistency.outcome.Outcome;
+
+
+/**************************************************************************
+ * Loads all mapfiles, and wraps marshalling/unmarshalling
+ *
+ * @author $Author: abranson $ $Date: 2004/10/20 14:10:21 $
+ * @version $Revision: 1.12 $
+ **************************************************************************/
+public class CastorXMLUtility
+{
+ private static Mapping mMapping = new Mapping();
+ private static HashSet<URL> mMappingKeys = new HashSet<URL>();
+
+ /**
+ * Looks for a file called 'index.xml' at the given URL, and loads every file
+ * listed in there by relative path
+ *
+ * @param mapURL - map root
+ */
+ static public void loadMapsFrom(URL mapURL) throws InvalidDataException {
+ // load index.xml
+ Logger.msg(3, "Loading maps from "+mapURL);
+ String index;
+ try {
+ index = FileStringUtility.url2String( new URL(mapURL, "index") );
+ } catch (Exception e) {
+ Logger.warning("Could not load map index from "+mapURL.toString());
+ return;
+ }
+
+ StringTokenizer sTokenizer = new StringTokenizer(index);
+ while( sTokenizer.hasMoreTokens() ) {
+ String thisMap = sTokenizer.nextToken();
+ try {
+ addMapping( new URL(mapURL, thisMap));
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new InvalidDataException("Error loading map '"+thisMap+"'", "");
+ }
+ }
+ Logger.msg("Loaded all maps from "+mapURL.toString());
+ }
+
+ /**************************************************************************
+ * Updates a mapping referenced by the mapID.
+ * The same mapping cannot be loaded many times as it generates an exception.
+ * That is the reason for this method as it maintains the HashSet of MappingKeys.
+ **************************************************************************/
+ static public void addMapping( URL mapID )
+ throws IOException,
+ MappingException,
+ MarshalException,
+ ValidationException
+ {
+
+ if( !mMappingKeys.contains(mapID) )
+ {
+ Logger.msg(7, "Added mapping file:"+mapID);
+
+ mMapping.loadMapping( mapID );
+ mMappingKeys.add( mapID );
+ }
+ else
+ {
+ Logger.msg("Map file already loaded:"+mapID);
+ }
+ }
+
+ /**************************************************************************
+ * Marshalls a mapped object to string. The mapping must be loaded before.
+ * See updateMapping().
+ **************************************************************************/
+ static public String marshall( Object obj )
+ throws IOException,
+ MappingException,
+ MarshalException,
+ ValidationException
+ {
+ if (obj == null) return "<NULL/>";
+ if (obj instanceof Outcome)
+ return ((Outcome)obj).getData();
+ StringWriter sWriter = new StringWriter();
+ Marshaller marshaller = new Marshaller( sWriter );
+
+ marshaller.setMapping( mMapping );
+ marshaller.setMarshalAsDocument( false );
+ marshaller.marshal( obj );
+
+ return sWriter.toString();
+ }
+
+ /**************************************************************************
+ * Unmarshalls a mapped object from string. The mapping must be loaded before.
+ * See updateMapping().
+ **************************************************************************/
+ static public Object unmarshall( String data )
+ throws IOException,
+ MappingException,
+ MarshalException,
+ ValidationException
+ {
+ StringReader sReader = new StringReader( data );
+ Unmarshaller unmarshaller = new Unmarshaller( mMapping );
+ if (data.equals("<NULL/>")) return null;
+ return unmarshaller.unmarshal( sReader );
+ }
+}
diff --git a/src/main/java/com/c2kernel/utils/DateUtility.java b/src/main/java/com/c2kernel/utils/DateUtility.java new file mode 100644 index 0000000..bc9fb05 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/DateUtility.java @@ -0,0 +1,118 @@ +package com.c2kernel.utils;
+import com.c2kernel.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/com/c2kernel/utils/FileStringUtility.java b/src/main/java/com/c2kernel/utils/FileStringUtility.java new file mode 100644 index 0000000..843a44e --- /dev/null +++ b/src/main/java/com/c2kernel/utils/FileStringUtility.java @@ -0,0 +1,432 @@ +package com.c2kernel.utils;
+
+//Java
+import java.io.BufferedInputStream;
+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.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
+ {
+ String resource = "";
+
+ BufferedInputStream file = new BufferedInputStream(location.openStream());
+ byte[] buffer = new byte[file.available()];
+
+ if (file.read(buffer) > 0)
+ resource = new String(buffer);
+
+ file.close();
+
+ return resource;
+ }
+
+ /**************************************************************************
+ * 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<String> lines = new Vector<String>();
+ String thisLine = null;
+ while ((thisLine = buf.readLine()) != null)
+ lines.addElement(thisLine);
+ 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<String> listDir(String dirPath, boolean withDirs, boolean recursive)
+ {
+ ArrayList<String> fileNames = new ArrayList<String>();
+ 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<String, String> loadLanguageFile(String configFile)
+ {
+ try
+ {
+ String language = FileStringUtility.file2String(configFile);
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ 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<String, String>();
+ }
+
+ }
+
+ /**************************************************************************
+ * 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<sourceb.length;i++)
+ {
+ if (sourceb[i]<'0'||(sourceb[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/com/c2kernel/utils/GTimeStampComparator.java b/src/main/java/com/c2kernel/utils/GTimeStampComparator.java new file mode 100644 index 0000000..8701b0e --- /dev/null +++ b/src/main/java/com/c2kernel/utils/GTimeStampComparator.java @@ -0,0 +1,25 @@ +package com.c2kernel.utils;
+
+import java.util.Comparator;
+
+import com.c2kernel.common.GTimeStamp;
+
+public class GTimeStampComparator implements Comparator<GTimeStamp> {
+
+ @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/com/c2kernel/utils/KeyValuePair.java b/src/main/java/com/c2kernel/utils/KeyValuePair.java new file mode 100644 index 0000000..5523eb6 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/KeyValuePair.java @@ -0,0 +1,77 @@ +package com.c2kernel.utils;
+
+
+public class KeyValuePair
+{
+ private String mKey = null;
+ private Object mValue = null;
+
+ public KeyValuePair() {}
+
+ public KeyValuePair(String key, Object value)
+ {
+ mKey = key;
+ mValue = value;
+ }
+
+ 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 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 Float getFloatValue() {
+ if (mValue instanceof Float)
+ return (Float)mValue;
+ else
+ return null;
+ }
+
+ public void setFloatValue(Float value) {
+ mValue = value;
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/utils/Language.java b/src/main/java/com/c2kernel/utils/Language.java new file mode 100644 index 0000000..0b71d16 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/Language.java @@ -0,0 +1,66 @@ +package com.c2kernel.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<Object, Object>();
+ public static Hashtable<String, String> mTableOfUntranslated = new Hashtable<String, String>();
+ public static boolean isTranlated=false;
+ private Hashtable<?, ?> tableOfTranslation = new Hashtable<Object, Object>();
+
+ 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<String> 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/com/c2kernel/utils/LocalObjectLoader.java b/src/main/java/com/c2kernel/utils/LocalObjectLoader.java new file mode 100644 index 0000000..8a73e3c --- /dev/null +++ b/src/main/java/com/c2kernel/utils/LocalObjectLoader.java @@ -0,0 +1,77 @@ +package com.c2kernel.utils;
+
+import com.c2kernel.common.InvalidDataException;
+import com.c2kernel.common.ObjectNotFoundException;
+import com.c2kernel.entity.proxy.ItemProxy;
+import com.c2kernel.lifecycle.ActivityDef;
+import com.c2kernel.lookup.DomainPath;
+import com.c2kernel.persistency.ClusterStorage;
+import com.c2kernel.persistency.ClusterStorageException;
+import com.c2kernel.persistency.outcome.Schema;
+import com.c2kernel.persistency.outcome.Viewpoint;
+import com.c2kernel.process.Gateway;
+
+public class LocalObjectLoader {
+ private static ActDefCache actCache = new ActDefCache();
+
+ static public ItemProxy loadLocalObjectDef(String root, String name)
+ throws ObjectNotFoundException
+ {
+ DomainPath defRoot = new DomainPath(root);
+ DomainPath defPath = (DomainPath)defRoot.find(name);
+ return (ItemProxy)Gateway.getProxyManager().getProxy(defPath);
+ }
+
+ static public String getScript(String scriptName, String 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 (ClusterStorageException 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);
+ Schema thisSchema = new Schema();
+ thisSchema.docType = schemaName;
+ thisSchema.docVersion = schemaVersion;
+
+ // don't bother if this is the Schema schema - for bootstrap esp.
+ if (schemaName.equals("Schema") && schemaVersion == 0) {
+ thisSchema.breakApart = false;
+ thisSchema.schema="";
+ return thisSchema;
+ }
+
+ ItemProxy schema = loadLocalObjectDef("/desc/OutcomeDesc/", schemaName);
+ Viewpoint schemaView = (Viewpoint)schema.getObject(ClusterStorage.VIEWPOINT + "/Schema/" + schemaVersion);
+ try {
+ thisSchema.schema = schemaView.getOutcome().getData();
+ } catch (ClusterStorageException ex) {
+ Logger.error(ex);
+ throw new ObjectNotFoundException("Problem loading schema "+schemaName+" v"+schemaVersion+": "+ex.getMessage(), "");
+ }
+ String breakApart = schema.getProperty("BreakApart");
+ thisSchema.breakApart = breakApart.equals("1");
+
+ return thisSchema;
+ }
+
+ /**
+ * 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, String actVersion) throws ObjectNotFoundException, InvalidDataException {
+ Logger.msg(5, "Loading activity def "+actName+" v"+actVersion);
+ return actCache.get(actName, actVersion);
+ }
+}
diff --git a/src/main/java/com/c2kernel/utils/Logger.java b/src/main/java/com/c2kernel/utils/Logger.java new file mode 100644 index 0000000..45edbee --- /dev/null +++ b/src/main/java/com/c2kernel/utils/Logger.java @@ -0,0 +1,194 @@ +package com.c2kernel.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 javax.swing.JOptionPane;
+
+import org.omg.CORBA.UserException;
+import org.tanukisoftware.wrapper.WrapperManager;
+
+import com.c2kernel.process.AbstractMain;
+import com.c2kernel.process.Gateway;
+import com.c2kernel.scripting.ScriptConsole;
+import com.c2kernel.utils.server.SimpleTCPIPServer;
+/**
+ * <pre>- 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);
+*</pre>
+ */
+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 HashMap<PrintStream, Integer> logStreams = new HashMap<PrintStream, Integer>();
+ static protected SimpleTCPIPServer mConsole = null;
+
+ static private void printMessage(String message, int msgLogLevel)
+ {
+ synchronized(logStreams) {
+ for (Iterator<PrintStream> iter = logStreams.keySet().iterator(); iter.hasNext();) {
+ PrintStream element = iter.next();
+ int logLevel = logStreams.get(element).intValue();
+ if (logLevel < msgLogLevel || (logLevel > 9 && logLevel - 10 < msgLogLevel))
+ continue;
+ if (logLevel > 9)
+ {
+ Timestamp ts = new Timestamp(System.currentTimeMillis());
+ String sTime = ts.toString();
+ message = sTime + " - " + message;
+ }
+ try {
+ element.println(message);
+ } catch (Exception ex) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ 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)
+ {
+ 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 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
+ */
+ 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);
+ if (AbstractMain.runningAsWrapper)
+ WrapperManager.stop(1);
+ else
+ System.exit(1);
+ }
+ static public void exceptionDialog(Exception ex)
+ {
+ String className = ex.getClass().getName();
+ className = className.substring(className.lastIndexOf('.') + 1);
+ String error = ex.getMessage();
+ if (ex instanceof UserException)
+ error = error.substring(error.indexOf(' ') + 1);
+ JOptionPane.showMessageDialog(null, error, className, JOptionPane.ERROR_MESSAGE);
+ }
+ /**
+ * @param console
+ */
+ public static void addLogStream(PrintStream console, int logLevel) {
+ try {
+ console.println("***********************************************************");
+ console.println(" C2Kernel 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, new Integer(logLevel));
+ if (logLevel > 9) logLevel-=10;
+ if (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 = -1;
+ for (Integer element : logStreams.values()) {
+ int thisLogLevel = element.intValue()>9?element.intValue()-10:element.intValue();
+ if (thisLogLevel > mHighestLogLevel || mHighestLogLevel == -1)
+ mHighestLogLevel = thisLogLevel;
+ }
+ }
+ }
+ }
+
+ static public void initConsole(String id)
+ {
+ String portString = Gateway.getProperty(id+".Console.port");
+ int port = 0;
+ try {
+ port = Integer.parseInt(portString);
+ } catch (NumberFormatException ex) {
+ Logger.msg("No port defined for "+id+" console. Using any port.");
+ }
+
+ mConsole = new SimpleTCPIPServer(port, ScriptConsole.class, 5);
+ mConsole.startListening();
+ Gateway.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/com/c2kernel/utils/Resource.java b/src/main/java/com/c2kernel/utils/Resource.java new file mode 100644 index 0000000..10228da --- /dev/null +++ b/src/main/java/com/c2kernel/utils/Resource.java @@ -0,0 +1,166 @@ +package com.c2kernel.utils;
+
+//Java
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import javax.swing.ImageIcon;
+
+import com.c2kernel.common.ObjectNotFoundException;
+
+/**************************************************************************
+ *
+ * @author $Author: abranson $ $Date: 2005/10/05 07:39:36 $
+ * @version $Revision: 1.71 $
+ **************************************************************************/
+public class Resource {
+ static private Hashtable<String, String> txtCache = new Hashtable<String, String>();
+ static private Hashtable<String, ImageIcon> imgCache = new Hashtable<String, ImageIcon>();
+ static private URL baseURL = getURLorResURL("com/c2kernel/utils/resources/");
+ static private HashMap<String, URL> moduleBaseURLs = new HashMap<String, URL>();
+ static public final ImageIcon nullImg = new ImageIcon(new byte[] { 0 });
+
+ public static URL getKernelBaseURL() {
+ return baseURL;
+ }
+
+ public static URL getKernelResourceURL(String resName) throws MalformedURLException {
+ return new URL(baseURL, resName);
+ }
+
+ public static void addModuleBaseURL(String ns, URL newBaseURL) {
+ moduleBaseURLs.put(ns, newBaseURL);
+ Logger.msg("Adding resource URL for "+ns+": "+newBaseURL.toString());
+ }
+
+ public static void addModuleBaseURL(String ns, String newBaseURL) {
+ addModuleBaseURL(ns, getURLorResURL(newBaseURL));
+ }
+
+ public static URL getModuleBaseURL(String ns) {
+ return moduleBaseURLs.get(ns);
+ }
+
+ public static HashMap<String, URL> getModuleBaseURLs() {
+ return moduleBaseURLs;
+ }
+
+ static public URL getModuleResourceURL(String ns, String resName) throws MalformedURLException {
+ return new URL(moduleBaseURLs.get(ns), resName);
+ }
+
+ private static URL getURLorResURL(String newURL) {
+ URL result;
+ try {
+ result = new URL(newURL);
+ } catch (java.net.MalformedURLException ex) {
+ //it is assumed that a 'wrong' URL denotes a directory
+ //of files resolvable from the CLASSPATH
+ result = Resource.class.getClassLoader().getResource(newURL);
+ }
+ return result;
+ }
+ /**************************************************************************
+ * Gets any text resource files
+ **************************************************************************/
+
+ static public String findTextResource(String resName) {
+ try {
+ for (String ns : getModuleBaseURLs().keySet()) {
+ try {
+ return getTextResource(ns, resName);
+ } catch (ObjectNotFoundException ex) { }
+ }
+ return getTextResource(null, resName);
+ } catch (ObjectNotFoundException ex) {
+ Logger.warning("Text resource '"+resName+"' not found.");
+ return null;
+ }
+ }
+
+ static public String getTextResource(String ns, String resName) throws ObjectNotFoundException
+ // throws IOException
+ {
+ Logger.msg(8, "Resource::getTextResource() - Getting resource: " + resName);
+
+ if (txtCache.containsKey(ns+'/'+resName)) {
+ return txtCache.get(ns+'/'+resName);
+ }
+
+ try {
+
+ String newRes = null;
+ URL loc;
+
+ if (ns == null) // kernel
+ loc = getKernelResourceURL(resName);
+ else
+ loc = getModuleResourceURL(ns, resName);
+ newRes = FileStringUtility.url2String(loc);
+ txtCache.put(ns+'/'+resName, newRes);
+ return newRes;
+ } catch (Exception e) {
+ throw new ObjectNotFoundException(e.getMessage(),null);
+ }
+ }
+ /**
+ * Gets an image from the resource directories
+ *
+ * @param resName - filename after resources/images
+ * @return
+ */
+ static public ImageIcon findImage(String resName) {
+ try {
+ for (String ns : getModuleBaseURLs().keySet()) {
+ try {
+ return getImage(ns, resName);
+ } catch (ObjectNotFoundException ex) { }
+ }
+ return getImage(null, resName);
+ } catch (ObjectNotFoundException ex) {
+ Logger.warning("Image '"+resName+"' not found. Using null icon");
+ return nullImg;
+ }
+ }
+
+ static public ImageIcon getImage(String ns, String resName) throws ObjectNotFoundException {
+ if (resName == null)
+ return nullImg;
+
+ if (imgCache.containsKey(ns+'/'+resName)) {
+ return imgCache.get(ns+'/'+resName);
+ }
+
+ URL imgLocation = null;
+ if (ns == null)
+ try {
+ imgLocation = getKernelResourceURL("images/"+resName);
+ } catch (MalformedURLException ex) { }
+ else
+ try {
+ imgLocation = getModuleResourceURL(ns, "images/"+resName);
+ } catch (MalformedURLException ex) { }
+
+ if (imgLocation!= null) {
+ ImageIcon newImg = new ImageIcon(imgLocation);
+
+ if (newImg.getIconHeight() > -1) {
+ imgCache.put(ns+'/'+resName, newImg);
+ Logger.msg(0, "Loaded "+resName+" "+newImg.getIconWidth()+"x"+newImg.getIconHeight());
+ return newImg;
+ }
+ }
+ throw new ObjectNotFoundException();
+ }
+
+ static public String getKernelVersion() {
+ try {
+ return FileStringUtility.url2String(getKernelResourceURL("textFiles/version.txt"));
+ } catch (Exception ex) {
+ return "No version info found";
+ }
+
+ }
+}
diff --git a/src/main/java/com/c2kernel/utils/SoftCache.java b/src/main/java/com/c2kernel/utils/SoftCache.java new file mode 100644 index 0000000..2fd79f1 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/SoftCache.java @@ -0,0 +1,113 @@ +package com.c2kernel.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<K, V> extends AbstractMap<K, V> {
+
+ private final Map<K, SoftValue<V>> hash = new HashMap<K, SoftValue<V>>();
+ private final int minSize;
+ private final LinkedList<V> hardCache = new LinkedList<V>();
+ private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
+
+ public SoftCache() {
+ this(0);
+ }
+
+ public SoftCache(int minSize) {
+ this.minSize = minSize;
+ }
+
+ @Override
+ public V get(Object key) {
+ V result = null;
+ SoftValue<V> 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
+ 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) {
+ hardCache.addFirst(value);
+ if (hardCache.size() > minSize)
+ hardCache.removeLast();
+ }
+ hash.put(key, new SoftValue<V>(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() {
+ hardCache.clear();
+ while(queue.poll()!=null);
+ hash.clear();
+ }
+
+ @Override
+ public int size() {
+ processQueue();
+ return hash.size();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ processQueue();
+ return hash.keySet();
+ }
+
+ @Override
+ public Set<Map.Entry<K, V>> 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<V> extends SoftReference<V> {
+ private final Object key;
+ private SoftValue(Object key, V value, ReferenceQueue<V> 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<V> sv;
+ while ((sv = (SoftValue<V>) queue.poll()) != null) {
+ hash.remove(sv.key);
+ }
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/utils/TransientCache.java b/src/main/java/com/c2kernel/utils/TransientCache.java new file mode 100644 index 0000000..d58617e --- /dev/null +++ b/src/main/java/com/c2kernel/utils/TransientCache.java @@ -0,0 +1,130 @@ +
+package com.c2kernel.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<K, V> extends AbstractMap<K, V> {
+
+ private Map<K, Reference<V>> map = new Hashtable<K, Reference<V>>();
+
+ @Override
+ public synchronized Set<Entry<K, V>> entrySet() {
+ Map<K, V> newMap = new Hashtable<K,V>();
+ Iterator<Entry<K, Reference<V>>> iter = map.entrySet().iterator();
+ while (iter.hasNext()) {
+ Entry<K, Reference<V>> me = iter.next();
+ Reference<V> 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<V> ref = makeReference(value);
+ ref = map.put(key, ref);
+ if (ref != null)
+ return (ref.get());
+ return null;
+ }
+
+ public abstract Reference<V> makeReference(Object value);
+
+ @Override
+ public V remove(Object key) {
+ Iterator<Entry<K, Reference<V>>> i = map.entrySet().iterator();
+ Entry<K, Reference<V>> correctEntry = null;
+ if (key == null) {
+ while (correctEntry == null && i.hasNext()) {
+ Entry<K, Reference<V>> e = i.next();
+ if (e.getKey() == null)
+ correctEntry = e;
+ }
+ } else {
+ while (correctEntry == null && i.hasNext()) {
+ Entry<K, Reference<V>> e = i.next();
+ if (key.equals(e.getKey()))
+ correctEntry = e;
+ }
+ }
+ V oldValue = null;
+ if (correctEntry != null) {
+ Reference<V> correctReference = correctEntry.getValue();
+ oldValue = correctReference.get();
+ i.remove();
+ }
+ return oldValue;
+ }
+ /**
+ *
+ */
+ @Override
+ public void clear() {
+ map.entrySet().clear();
+ }
+
+ private transient Set<K> keySet = null;
+
+ @Override
+ public Set<K> keySet() {
+ if (keySet == null) {
+ keySet = new AbstractSet<K>() {
+ @Override
+ public Iterator<K> iterator() {
+ return new Iterator<K>() {
+ private Iterator<Entry<K, Reference<V>>> 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/com/c2kernel/utils/XmlElementParser.java b/src/main/java/com/c2kernel/utils/XmlElementParser.java new file mode 100644 index 0000000..2e86763 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/XmlElementParser.java @@ -0,0 +1,105 @@ +package com.c2kernel.utils;
+
+import java.io.StringReader;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+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<String> returnData = new Vector<String>();
+ String[] returnArray = new String[0];
+ try
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ StringReader is = new StringReader(data);
+ Document doc = builder.parse(new InputSource(is));
+ 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);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ //Logger.error(e);
+ }
+ Logger.msg(3, returnData.size()+" values found for "+xpath);
+ returnArray=new String[returnData.size()];
+ for (int i=0;i<returnArray.length;i++)
+ returnArray[i] = returnData.get(i);
+ return returnArray;
+ }
+}
diff --git a/src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java b/src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java new file mode 100644 index 0000000..886ae9f --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/HTTPRequestHandler.java @@ -0,0 +1,160 @@ +package com.c2kernel.utils.server;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import com.c2kernel.utils.Logger;
+
+public class HTTPRequestHandler implements SocketHandler {
+
+ protected HashMap<String, String> headers = new HashMap<String, String>();
+ protected String method;
+ protected String resource;
+ protected String version;
+ protected String returnMIME;
+ protected String statusCode;
+ protected String postData;
+ protected final static String CRLF = "\r\n";
+ protected BufferedReader request;
+ protected Socket currentSocket = null;
+
+ public HTTPRequestHandler() { }
+
+ @Override
+ public String getName() {
+ return "HTTP Server";
+ }
+
+ @Override
+ public boolean isBusy() {
+ return (currentSocket!=null);
+ }
+
+ @Override
+ public void setSocket(Socket newSocket) {
+ currentSocket = newSocket;
+ }
+
+ @Override
+ public void shutdown() {
+ try {
+ if (currentSocket != null) currentSocket.close();
+ } catch (IOException e) {
+ Logger.error("Error shutting down HTTP connection");
+ }
+ currentSocket = null;
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName("HTTP Request Handler");
+ try {
+ request = new BufferedReader(new InputStreamReader(currentSocket.getInputStream()));
+ // parse the request
+ boolean firstLine = true;
+ String headerLine;
+ do {
+ headerLine = request.readLine();
+ if (headerLine == null)
+ throw new IOException("Disconnected");
+ if (firstLine) { // request line
+ StringTokenizer params = new StringTokenizer(headerLine);
+ try {
+ method = params.nextToken();
+ resource = params.nextToken();
+ version = params.nextToken();
+ } catch (NoSuchElementException ex1) { } // incomplete request line - doesn't matter
+ firstLine = false;
+ }
+ else { // headers
+ int split = headerLine.indexOf(": ");
+ if (split >= 0)
+ headers.put(
+ headerLine.substring(0, split),
+ headerLine.substring(split+2)
+ );
+ }
+ } while (!headerLine.equals(CRLF) && !headerLine.equals(""));
+
+ String response = null;
+
+ try {
+
+ if (headers.containsKey("Content-length")) { // read POST data
+ StringBuffer postBuffer = new StringBuffer();
+ int received = 0; int length = Integer.parseInt(headers.get("Content-length"));
+ try {
+ while (received < length) {
+ String postLine = request.readLine();
+ postBuffer.append(postLine);
+ received+=postLine.length();
+ }
+ } catch (IOException ex) {
+ Logger.error("Error reading post data. "+received+" bytes of "+length+" received. ("+(received*100.0/length)+"%");
+ Logger.error(ex);
+ throw ex;
+ }
+ }
+ // Got the params, generate response
+
+ returnMIME = "text/xml";
+ statusCode = "200 OK";
+
+ response = processRequest();
+ } catch (Exception ex3) {
+ response = error("500 Server Error", ex3.getClass().getName()+"<br>"+ex3.getMessage());
+ }
+ System.out.println(new Date().toString()+" "+currentSocket.getInetAddress()+" "+method+" "+resource+" "+statusCode);
+
+ OutputStream output = currentSocket.getOutputStream();
+
+ statusCode = "HTTP/1.0 "+statusCode+CRLF;
+ output.write(statusCode.getBytes());
+
+ returnMIME = "Content-type: "+returnMIME+CRLF;
+ output.write(returnMIME.getBytes());
+
+ String contentLength = "Content-Length: "+response.length()+CRLF;
+ output.write(contentLength.getBytes());
+
+ // Possible: last mod?
+ // end of headers
+ output.write(CRLF.getBytes());
+
+ // write the content
+ output.write(response.getBytes());
+ request.close();
+ output.close();
+ currentSocket.close();
+ } catch (IOException ex2) {
+ Logger.error(ex2);
+ } // aborted connection probably
+ currentSocket = null;
+ }
+
+ /* This is a dummy method that doesn't support anything.
+ * Override it.
+ */
+
+ public String processRequest() {
+ return error("501 Not Implemented", "The method "+method+" you have requested is not supported by this server.");
+ }
+
+ public String error(String code, String desc) {
+ statusCode = code;
+ returnMIME = "text/html";
+ return ("<HTML>" +
+ "<HEAD><TITLE>"+code+"</TITLE></HEAD>" +
+ "<BODY><h1>"+code+"</h1>" +
+ "<p>"+desc+
+ "<hr><p><small>Cristal Item HTTP server</small></BODY></HTML>");
+ }
+}
+
diff --git a/src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java b/src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java new file mode 100644 index 0000000..930fcee --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/SimpleTCPIPServer.java @@ -0,0 +1,109 @@ +package com.c2kernel.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 com.c2kernel.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<SocketHandler> currentHandlers = new ArrayList<SocketHandler>();
+ 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<SocketHandler> 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/com/c2kernel/utils/server/SocketHandler.java b/src/main/java/com/c2kernel/utils/server/SocketHandler.java new file mode 100644 index 0000000..8d37714 --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/SocketHandler.java @@ -0,0 +1,15 @@ +package com.c2kernel.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();
+}
+
diff --git a/src/main/java/com/c2kernel/utils/server/UDPListener.java b/src/main/java/com/c2kernel/utils/server/UDPListener.java new file mode 100644 index 0000000..3b1fc9d --- /dev/null +++ b/src/main/java/com/c2kernel/utils/server/UDPListener.java @@ -0,0 +1,54 @@ +package com.c2kernel.utils.server;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+
+import com.c2kernel.common.InvalidDataException;
+import com.c2kernel.utils.Logger;
+
+/**************************************************************************
+ *
+ * $Revision: 1.2 $
+ * $Date: 2004/02/06 14:50:43 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+public abstract class UDPListener extends Thread {
+
+ private boolean active = true;
+ protected DatagramSocket socket;
+
+ public UDPListener() {
+ super();
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName("UDP Server");
+ byte[] buffer = new byte[255];
+ DatagramPacket newPacket = new DatagramPacket(buffer, buffer.length);
+ while (active) {
+ try {
+ socket.receive(newPacket);
+ processPacket(newPacket);
+ } catch (InterruptedIOException e) { // ignore timeout
+ } catch (IOException e) {
+ Logger.error("Error receiving proxy packet:");
+ Logger.error(e);
+ } catch (InvalidDataException e) {
+ Logger.error(e);
+ }
+ }
+ socket.close();
+ }
+
+ protected abstract void processPacket(DatagramPacket packet) throws InvalidDataException;
+
+ public void shutdown() {
+ active = false;
+ }
+}
|
