From f567b9f58915e30a57245ac564636379a5cc26ac Mon Sep 17 00:00:00 2001 From: idfx Date: Tue, 28 Jan 2003 21:47:42 +0000 Subject: [PATCH] some codeformatting, license for the new classes --- source/mir/config/ConfigChecker.java | 270 +- source/mir/config/ConfigNode.java | 48 +- source/mir/config/ConfigNodeBuilder.java | 14 +- source/mir/config/ConfigReader.java | 523 ++-- source/mir/config/ConfigSimpleNode.java | 465 ++-- source/mir/config/MirConfiguration.java | 55 +- source/mir/config/MirPropertiesConfiguration.java | 120 +- .../exceptions/ConfigDefineNotKnownException.java | 13 +- source/mir/config/exceptions/ConfigFailure.java | 16 +- .../ConfigInvalidPropertyTypeException.java | 13 +- .../exceptions/ConfigMissingPropertyException.java | 13 +- source/mir/storage/Database.java | 2784 +++++++++++--------- source/mir/storage/DatabaseAdaptor.java | 196 +- source/mir/storage/DatabaseAdaptorMySQL.java | 144 +- source/mir/storage/DatabaseAdaptorOracle.java | 130 +- source/mir/storage/DatabaseAdaptorPostgresql.java | 144 +- source/mir/storage/DatabaseAdaptorSybase.java | 220 +- source/mir/storage/DatabaseCache.java | 118 +- source/mir/storage/StorageObject.java | 462 ++-- source/mir/storage/StorageObjectExc.java | 36 +- source/mir/storage/StorageObjectException.java | 71 - source/mir/storage/StorageObjectFailure.java | 48 +- 22 files changed, 3018 insertions(+), 2885 deletions(-) delete mode 100755 source/mir/storage/StorageObjectException.java diff --git a/source/mir/config/ConfigChecker.java b/source/mir/config/ConfigChecker.java index d74474b9..71d19c47 100755 --- a/source/mir/config/ConfigChecker.java +++ b/source/mir/config/ConfigChecker.java @@ -28,139 +28,149 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config; + +import mir.config.exceptions.ConfigFailure; -package mir.config; - import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Vector; -import mir.config.exceptions.ConfigFailure; - -public class ConfigChecker { - public final static int STRING = 0; - public final static int INTEGER = 1; - public final static int BOOLEAN = 2; - public final static int DOUBLE = 3; - public final static int PATH = 4; -// public final static int ABSOLUTEPATH = 5; -// public final static int ABSOLUTEURL = 6; - - private Node rootNode; - - public Node getRootNode() { - return rootNode; - } - - public ConfigChecker() { - super(); - - rootNode = new Node(); - } - - public void check(ConfigNode aNode) throws ConfigFailure { - getRootNode().check(aNode); - } - - public class Node { - - private Map subNodes; - private Vector constraints; - - public Node() { - subNodes = new HashMap(); - constraints = new Vector(); - } - - public Node getSubNode(String aName) { - Node subNode = (Node) subNodes.get(aName); - - if (subNode==null) { - subNode = new Node(); - subNodes.put(aName, subNode); - } - - return subNode; - } - - public void addExistenceConstraint(String aPropertyName) { - constraints.add(new ExistenceConstraint(aPropertyName)); - } - - public void addTypeConstraint(String aPropertyName, int aType) { - constraints.add(new TypeConstraint(aPropertyName, aType)); - } - - public void addExistenceAndTypeConstraint(String aPropertyName, int aType) { - addExistenceConstraint(aPropertyName); - addTypeConstraint(aPropertyName, aType); - } - - public void check(ConfigNode aNode) throws ConfigFailure { - Iterator iterator; - - iterator=constraints.iterator(); - while (iterator.hasNext()) { - ((Constraint) iterator.next()).check(aNode); - } - - iterator=subNodes.keySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - ((Node) entry.getValue()).check(aNode.getSubNode((String) entry.getKey())); - } - - } - - private class Constraint { - protected String propertyName; - - Constraint(String aPropertyName) { - propertyName=aPropertyName; - } - - public void check(ConfigNode aNode) throws ConfigFailure { - }; - } - - private class ExistenceConstraint extends Constraint { - ExistenceConstraint(String aPropertyName) { - super(aPropertyName); - } - - public void check(ConfigNode aNode) throws ConfigFailure { - aNode.getRequiredStringProperty(propertyName); - }; - } - - private class TypeConstraint extends Constraint { - private int type; - - TypeConstraint(String aPropertyName, int aType) { - super(aPropertyName); - - type=aType; - } - - public void check(ConfigNode aNode) throws ConfigFailure { - switch(type) { - case INTEGER: - aNode.getOptionalIntegerProperty(propertyName, new Integer(0)); - break; - case STRING: - aNode.getOptionalStringProperty(propertyName, ""); - break; - case DOUBLE: - aNode.getOptionalDoubleProperty(propertyName, new Double(0.0)); - break; - case BOOLEAN: - aNode.getOptionalBooleanProperty(propertyName, Boolean.FALSE); - break; - default: - throw new ConfigFailure("Invalid value for type in type constraint: "+new Integer(type).toString()); - } - } - } - } -} + +public class ConfigChecker { + public final static int STRING = 0; + public final static int INTEGER = 1; + public final static int BOOLEAN = 2; + public final static int DOUBLE = 3; + public final static int PATH = 4; + + // public final static int ABSOLUTEPATH = 5; + // public final static int ABSOLUTEURL = 6; + private Node rootNode; + + public ConfigChecker() { + super(); + + rootNode = new Node(); + } + + public Node getRootNode() { + return rootNode; + } + + public void check(ConfigNode aNode) throws ConfigFailure { + getRootNode().check(aNode); + } + + public class Node { + private Map subNodes; + private Vector constraints; + + public Node() { + subNodes = new HashMap(); + constraints = new Vector(); + } + + public Node getSubNode(String aName) { + Node subNode = (Node) subNodes.get(aName); + + if (subNode == null) { + subNode = new Node(); + subNodes.put(aName, subNode); + } + + return subNode; + } + + public void addExistenceConstraint(String aPropertyName) { + constraints.add(new ExistenceConstraint(aPropertyName)); + } + + public void addTypeConstraint(String aPropertyName, int aType) { + constraints.add(new TypeConstraint(aPropertyName, aType)); + } + + public void addExistenceAndTypeConstraint(String aPropertyName, int aType) { + addExistenceConstraint(aPropertyName); + addTypeConstraint(aPropertyName, aType); + } + + public void check(ConfigNode aNode) throws ConfigFailure { + Iterator iterator; + + iterator = constraints.iterator(); + + while (iterator.hasNext()) { + ((Constraint) iterator.next()).check(aNode); + } + + iterator = subNodes.keySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry) iterator.next(); + ((Node) entry.getValue()).check(aNode.getSubNode( + (String) entry.getKey())); + } + } + + private class Constraint { + protected String propertyName; + + Constraint(String aPropertyName) { + propertyName = aPropertyName; + } + + public void check(ConfigNode aNode) throws ConfigFailure { + } + } + + private class ExistenceConstraint extends Constraint { + ExistenceConstraint(String aPropertyName) { + super(aPropertyName); + } + + public void check(ConfigNode aNode) throws ConfigFailure { + aNode.getRequiredStringProperty(propertyName); + } + } + + private class TypeConstraint extends Constraint { + private int type; + + TypeConstraint(String aPropertyName, int aType) { + super(aPropertyName); + + type = aType; + } + + public void check(ConfigNode aNode) throws ConfigFailure { + switch (type) { + case INTEGER: + aNode.getOptionalIntegerProperty(propertyName, new Integer(0)); + + break; + + case STRING: + aNode.getOptionalStringProperty(propertyName, ""); + + break; + + case DOUBLE: + aNode.getOptionalDoubleProperty(propertyName, new Double(0.0)); + + break; + + case BOOLEAN: + aNode.getOptionalBooleanProperty(propertyName, Boolean.FALSE); + + break; + + default: + throw new ConfigFailure("Invalid value for type in type constraint: " + + new Integer(type).toString()); + } + } + } + } +} diff --git a/source/mir/config/ConfigNode.java b/source/mir/config/ConfigNode.java index 40a615e5..468ed989 100755 --- a/source/mir/config/ConfigNode.java +++ b/source/mir/config/ConfigNode.java @@ -28,21 +28,37 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config; -package mir.config; - import mir.config.exceptions.ConfigFailure; - -public interface ConfigNode { - public String getLocationDescription(); - - public ConfigNode getSubNode(String aSubNodeName); - public Boolean getRequiredBooleanProperty(String aPropertyName) throws ConfigFailure; - public Integer getRequiredIntegerProperty(String aPropertyName) throws ConfigFailure; - public String getRequiredStringProperty(String aPropertyName) throws ConfigFailure; - public Double getRequiredDoubleProperty(String aPropertyName) throws ConfigFailure; - public Boolean getOptionalBooleanProperty(String aPropertyName, Boolean aDefaultValue) throws ConfigFailure; - public Integer getOptionalIntegerProperty(String aPropertyName, Integer aDefaultValue) throws ConfigFailure; - public String getOptionalStringProperty(String aPropertyName, String aDefaultValue) throws ConfigFailure; - public Double getOptionalDoubleProperty(String aPropertyName, Double aDefaultValue) throws ConfigFailure; -} + + +public interface ConfigNode { + public String getLocationDescription(); + + public ConfigNode getSubNode(String aSubNodeName); + + public Boolean getRequiredBooleanProperty(String aPropertyName) + throws ConfigFailure; + + public Integer getRequiredIntegerProperty(String aPropertyName) + throws ConfigFailure; + + public String getRequiredStringProperty(String aPropertyName) + throws ConfigFailure; + + public Double getRequiredDoubleProperty(String aPropertyName) + throws ConfigFailure; + + public Boolean getOptionalBooleanProperty(String aPropertyName, + Boolean aDefaultValue) throws ConfigFailure; + + public Integer getOptionalIntegerProperty(String aPropertyName, + Integer aDefaultValue) throws ConfigFailure; + + public String getOptionalStringProperty(String aPropertyName, + String aDefaultValue) throws ConfigFailure; + + public Double getOptionalDoubleProperty(String aPropertyName, + Double aDefaultValue) throws ConfigFailure; +} diff --git a/source/mir/config/ConfigNodeBuilder.java b/source/mir/config/ConfigNodeBuilder.java index 94e0f101..b85c10a5 100755 --- a/source/mir/config/ConfigNodeBuilder.java +++ b/source/mir/config/ConfigNodeBuilder.java @@ -28,11 +28,11 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config; -package mir.config; - - -public interface ConfigNodeBuilder { - public ConfigNodeBuilder makeSubNode(String aName, String aLocationDescription); - public void addProperty(String aName, String aValue, String aValueDescription, String aLocationDescription); -} +public interface ConfigNodeBuilder { + public ConfigNodeBuilder makeSubNode(String aName, String aLocationDescription); + + public void addProperty(String aName, String aValue, + String aValueDescription, String aLocationDescription); +} diff --git a/source/mir/config/ConfigReader.java b/source/mir/config/ConfigReader.java index e1e69da4..564a79a3 100755 --- a/source/mir/config/ConfigReader.java +++ b/source/mir/config/ConfigReader.java @@ -28,13 +28,24 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config; + +import mir.config.exceptions.ConfigDefineNotKnownException; +import mir.config.exceptions.ConfigFailure; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.xml.sax.helpers.DefaultHandler; -package mir.config; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; + import java.util.HashMap; import java.util.Map; import java.util.Stack; @@ -43,259 +54,257 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import mir.config.exceptions.ConfigDefineNotKnownException; -import mir.config.exceptions.ConfigFailure; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; - -public class ConfigReader { - final static String propertyTagName="property"; - final static String propertyNameAttribute="name"; - final static String propertyValueAttribute="value"; - final static String defineTagName="define"; - final static String defineNameAttribute="name"; - final static String defineValueAttribute="value"; - final static String includeTagName="include"; - final static String includeFileAttribute="file"; - - public ConfigReader() { - super(); - }; - - public void parseFile(String aFileName, ConfigNodeBuilder aRootNode) throws ConfigFailure { - - try { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - - parserFactory.setNamespaceAware(false); - parserFactory.setValidating(true); - - - ConfigReaderHandler handler = new ConfigReaderHandler(aRootNode, parserFactory); - - handler.includeFile(aFileName); - } - catch (Throwable e) { - if (e instanceof SAXParseException && ((SAXParseException) e).getException() instanceof ConfigFailure) { - throw (ConfigFailure) ((SAXParseException) e).getException(); - } - else { - e.printStackTrace(); - throw new ConfigFailure( e.getMessage() ); - } - } - } - - private class ConfigReaderHandler extends DefaultHandler { - ConfigNodeBuilder builder; - Stack nodeStack; - Locator locator; - DefinesManager definesManager; - int level; - Stack includeFileStack; - SAXParserFactory parserFactory; - - public ConfigReaderHandler(ConfigNodeBuilder aBuilder, SAXParserFactory aParserFactory) { - super(); - - builder=aBuilder; - nodeStack=new Stack(); - includeFileStack=new Stack(); - definesManager=new DefinesManager(); - parserFactory=aParserFactory; - level=0; - } - - public String getLocatorDescription(Locator aLocator) { - return aLocator.getPublicId()+" ("+aLocator.getLineNumber()+")"; - } - - public void setDocumentLocator(Locator aLocator) { - locator=aLocator; - } - - private void includeFile(String aFileName) throws ConfigFailure, SAXParseException, SAXException { - File file; - SAXParser parser; - InputSource inputSource; - System.err.println("about to include "+aFileName); - - try { - if (!includeFileStack.empty()) - file = new File(new File((String) includeFileStack.peek()).getParent(), aFileName); - else - file = new File(aFileName); - - System.err.println("about to include "+file.getCanonicalPath()); - - if (includeFileStack.contains(file.getCanonicalPath())) { - throw new ConfigFailure("recursive inclusion of file "+file.getCanonicalPath(), getLocatorDescription(locator)); - } - - parser=parserFactory.newSAXParser(); - - inputSource = new InputSource(new FileInputStream(file)); - inputSource.setPublicId(file.getCanonicalPath()); - - includeFileStack.push(file.getCanonicalPath()); - try { - parser.parse(inputSource, this); - } - finally { - includeFileStack.pop(); - } - } - catch (ParserConfigurationException e) { - throw new ConfigFailure("Internal exception while including \""+aFileName+"\": "+e.getMessage(), e, getLocatorDescription(locator)); - } - catch (SAXParseException e) { - throw e; - } - catch (ConfigFailure e) { - throw e; - } - catch (FileNotFoundException e) { - throw new ConfigFailure("Include file \""+aFileName+"\" not found: "+e.getMessage(), e, getLocatorDescription(locator)); - } - catch (IOException e) { - throw new ConfigFailure("unable to open include file \""+aFileName+"\": "+e.getMessage(), e, getLocatorDescription(locator)); - } - - } - - public void startElement(String aUri, String aTag, String aQualifiedName, Attributes anAttributes) throws SAXException { - nodeStack.push(builder); - level++; - try { - if (builder==null) { - throw new ConfigFailure("define, include and property tags cannot have content", getLocatorDescription(locator)); - } - if (aQualifiedName.equals(propertyTagName)) { - String name=anAttributes.getValue(propertyNameAttribute); - String value=anAttributes.getValue(propertyValueAttribute); - - if (name==null) { - throw new ConfigFailure("property has no name attribute", getLocatorDescription(locator)); - } - else - if (value==null) { - throw new ConfigFailure("property \""+name+"\" has no value attribute", getLocatorDescription(locator)); - } - - builder.addProperty(name, definesManager.resolve(value, getLocatorDescription(locator)), value, getLocatorDescription(locator)); - builder=null; - - } - else if (aQualifiedName.equals(defineTagName)) { - String name=anAttributes.getValue(defineNameAttribute); - String value=anAttributes.getValue(defineValueAttribute); - - if (name==null) { - throw new ConfigFailure("define has no name attribute", getLocatorDescription(locator)); - } - else - if (value==null) { - throw new ConfigFailure("define \""+name+"\" has no value attribute", getLocatorDescription(locator)); - } - - definesManager.addDefine(name, definesManager.resolve(value, getLocatorDescription(locator))); - builder=null; - } - else if (aQualifiedName.equals(includeTagName)) { - String fileName=anAttributes.getValue(includeFileAttribute); - - if (fileName==null) { - throw new ConfigFailure("include has no file attribute", getLocatorDescription(locator)); - } - - includeFile(definesManager.resolve(fileName, getLocatorDescription(locator))); - builder=null; - } - else - { - builder=builder.makeSubNode(aQualifiedName, getLocatorDescription(locator)); - } - } - catch (ConfigFailure e) { - throw new SAXParseException(e.getMessage(), locator, e); - } - } - - public void endElement(String aUri, String aTag, String aQualifiedName) throws SAXParseException { - builder=(ConfigNodeBuilder) nodeStack.pop(); - level--; - } - - public void characters(char[] aBuffer, int aStart, int anEnd) throws SAXParseException { - String text = new String(aBuffer, aStart, anEnd).trim(); - if ( text.length() > 0) { - throw new SAXParseException("Text not allowed", locator, new ConfigFailure("text not allowed", getLocatorDescription(locator))); - } - } - } - - private class DefinesManager { - Map defines; - - public DefinesManager() { - defines = new HashMap(); - } - - public void addDefine(String aName, String anExpression) { - defines.put(aName, anExpression); - } - - public String resolve(String anExpression, String aLocation) throws ConfigFailure { - int previousPosition = 0; - int position; - int endOfNamePosition; - String name; - - StringBuffer result = new StringBuffer(); - - while ((position=anExpression.indexOf("$", previousPosition))>=0) { - result.append(anExpression.substring(previousPosition, position)); - - if (position>=anExpression.length()-1) { - result.append(anExpression.substring(position, anExpression.length())); - previousPosition=anExpression.length(); - } - else - { - if (anExpression.charAt(position+1) == '{') { - endOfNamePosition=anExpression.indexOf('}', position); - if (endOfNamePosition>=0) { - name=anExpression.substring(position+2, endOfNamePosition); - if (defines.containsKey(name)) { - result.append((String) defines.get(name)); - previousPosition=endOfNamePosition+1; - } - else { - throw new ConfigDefineNotKnownException("Variable \""+name+"\" not defined", aLocation); - } - } - else { - throw new ConfigFailure("Missing }", aLocation); - } - - } - else - { - previousPosition=position+2; - result.append(anExpression.charAt(position+1)); - } - } - } - result.append(anExpression.substring(previousPosition, anExpression.length())); - - return result.toString(); - } - } -} - - +public class ConfigReader { + final static String propertyTagName = "property"; + final static String propertyNameAttribute = "name"; + final static String propertyValueAttribute = "value"; + final static String defineTagName = "define"; + final static String defineNameAttribute = "name"; + final static String defineValueAttribute = "value"; + final static String includeTagName = "include"; + final static String includeFileAttribute = "file"; + + public ConfigReader() { + super(); + } + + public void parseFile(String aFileName, ConfigNodeBuilder aRootNode) + throws ConfigFailure { + try { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + + parserFactory.setNamespaceAware(false); + parserFactory.setValidating(true); + + ConfigReaderHandler handler = + new ConfigReaderHandler(aRootNode, parserFactory); + + handler.includeFile(aFileName); + } catch (Throwable e) { + if (e instanceof SAXParseException && + ((SAXParseException) e).getException() instanceof ConfigFailure) { + throw (ConfigFailure) ((SAXParseException) e).getException(); + } else { + e.printStackTrace(); + throw new ConfigFailure(e.getMessage()); + } + } + } + + private class ConfigReaderHandler extends DefaultHandler { + ConfigNodeBuilder builder; + Stack nodeStack; + Locator locator; + DefinesManager definesManager; + int level; + Stack includeFileStack; + SAXParserFactory parserFactory; + + public ConfigReaderHandler(ConfigNodeBuilder aBuilder, + SAXParserFactory aParserFactory) { + super(); + + builder = aBuilder; + nodeStack = new Stack(); + includeFileStack = new Stack(); + definesManager = new DefinesManager(); + parserFactory = aParserFactory; + level = 0; + } + + public String getLocatorDescription(Locator aLocator) { + return aLocator.getPublicId() + " (" + aLocator.getLineNumber() + ")"; + } + + public void setDocumentLocator(Locator aLocator) { + locator = aLocator; + } + + private void includeFile(String aFileName) + throws ConfigFailure, SAXParseException, SAXException { + File file; + SAXParser parser; + InputSource inputSource; + System.err.println("about to include " + aFileName); + + try { + if (!includeFileStack.empty()) { + file = + new File(new File((String) includeFileStack.peek()).getParent(), + aFileName); + } else { + file = new File(aFileName); + } + + System.err.println("about to include " + file.getCanonicalPath()); + + if (includeFileStack.contains(file.getCanonicalPath())) { + throw new ConfigFailure("recursive inclusion of file " + + file.getCanonicalPath(), getLocatorDescription(locator)); + } + + parser = parserFactory.newSAXParser(); + + inputSource = new InputSource(new FileInputStream(file)); + inputSource.setPublicId(file.getCanonicalPath()); + + includeFileStack.push(file.getCanonicalPath()); + + try { + parser.parse(inputSource, this); + } finally { + includeFileStack.pop(); + } + } catch (ParserConfigurationException e) { + throw new ConfigFailure("Internal exception while including \"" + + aFileName + "\": " + e.getMessage(), e, getLocatorDescription(locator)); + } catch (SAXParseException e) { + throw e; + } catch (ConfigFailure e) { + throw e; + } catch (FileNotFoundException e) { + throw new ConfigFailure("Include file \"" + aFileName + + "\" not found: " + e.getMessage(), e, getLocatorDescription(locator)); + } catch (IOException e) { + throw new ConfigFailure("unable to open include file \"" + aFileName + + "\": " + e.getMessage(), e, getLocatorDescription(locator)); + } + } + + public void startElement(String aUri, String aTag, String aQualifiedName, + Attributes anAttributes) throws SAXException { + nodeStack.push(builder); + level++; + + try { + if (builder == null) { + throw new ConfigFailure("define, include and property tags cannot have content", + getLocatorDescription(locator)); + } + + if (aQualifiedName.equals(propertyTagName)) { + String name = anAttributes.getValue(propertyNameAttribute); + String value = anAttributes.getValue(propertyValueAttribute); + + if (name == null) { + throw new ConfigFailure("property has no name attribute", + getLocatorDescription(locator)); + } else if (value == null) { + throw new ConfigFailure("property \"" + name + + "\" has no value attribute", getLocatorDescription(locator)); + } + + builder.addProperty(name, + definesManager.resolve(value, getLocatorDescription(locator)), + value, getLocatorDescription(locator)); + builder = null; + } else if (aQualifiedName.equals(defineTagName)) { + String name = anAttributes.getValue(defineNameAttribute); + String value = anAttributes.getValue(defineValueAttribute); + + if (name == null) { + throw new ConfigFailure("define has no name attribute", + getLocatorDescription(locator)); + } else if (value == null) { + throw new ConfigFailure("define \"" + name + + "\" has no value attribute", getLocatorDescription(locator)); + } + + definesManager.addDefine(name, + definesManager.resolve(value, getLocatorDescription(locator))); + builder = null; + } else if (aQualifiedName.equals(includeTagName)) { + String fileName = anAttributes.getValue(includeFileAttribute); + + if (fileName == null) { + throw new ConfigFailure("include has no file attribute", + getLocatorDescription(locator)); + } + + includeFile(definesManager.resolve(fileName, + getLocatorDescription(locator))); + builder = null; + } else { + builder = + builder.makeSubNode(aQualifiedName, getLocatorDescription(locator)); + } + } catch (ConfigFailure e) { + throw new SAXParseException(e.getMessage(), locator, e); + } + } + + public void endElement(String aUri, String aTag, String aQualifiedName) + throws SAXParseException { + builder = (ConfigNodeBuilder) nodeStack.pop(); + level--; + } + + public void characters(char[] aBuffer, int aStart, int anEnd) + throws SAXParseException { + String text = new String(aBuffer, aStart, anEnd).trim(); + + if (text.length() > 0) { + throw new SAXParseException("Text not allowed", locator, + new ConfigFailure("text not allowed", getLocatorDescription(locator))); + } + } + } + + private class DefinesManager { + Map defines; + + public DefinesManager() { + defines = new HashMap(); + } + + public void addDefine(String aName, String anExpression) { + defines.put(aName, anExpression); + } + + public String resolve(String anExpression, String aLocation) + throws ConfigFailure { + int previousPosition = 0; + int position; + int endOfNamePosition; + String name; + + StringBuffer result = new StringBuffer(); + + while ((position = anExpression.indexOf("$", previousPosition)) >= 0) { + result.append(anExpression.substring(previousPosition, position)); + + if (position >= (anExpression.length() - 1)) { + result.append(anExpression.substring(position, anExpression.length())); + previousPosition = anExpression.length(); + } else { + if (anExpression.charAt(position + 1) == '{') { + endOfNamePosition = anExpression.indexOf('}', position); + + if (endOfNamePosition >= 0) { + name = anExpression.substring(position + 2, endOfNamePosition); + + if (defines.containsKey(name)) { + result.append((String) defines.get(name)); + previousPosition = endOfNamePosition + 1; + } else { + throw new ConfigDefineNotKnownException("Variable \"" + name + + "\" not defined", aLocation); + } + } else { + throw new ConfigFailure("Missing }", aLocation); + } + } else { + previousPosition = position + 2; + result.append(anExpression.charAt(position + 1)); + } + } + } + + result.append(anExpression.substring(previousPosition, + anExpression.length())); + + return result.toString(); + } + } +} diff --git a/source/mir/config/ConfigSimpleNode.java b/source/mir/config/ConfigSimpleNode.java index 70f20adf..7d0c1850 100755 --- a/source/mir/config/ConfigSimpleNode.java +++ b/source/mir/config/ConfigSimpleNode.java @@ -28,237 +28,242 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config; + +import mir.config.exceptions.ConfigInvalidPropertyTypeException; +import mir.config.exceptions.ConfigMissingPropertyException; -package mir.config; - import java.util.HashMap; import java.util.Map; -import mir.config.exceptions.ConfigInvalidPropertyTypeException; -import mir.config.exceptions.ConfigMissingPropertyException; - -public class ConfigSimpleNode implements ConfigNode, ConfigNodeBuilder { - private Map properties; - private Map subNodes; - private String locationDescription; - private String path; - - public ConfigSimpleNode() { - this("", ""); - } - - public ConfigSimpleNode(String aLocationDescription) { - this("", aLocationDescription); - } - - public ConfigSimpleNode(String aPath, String aLocationDescription) { - super (); - - path = aPath; - locationDescription = aLocationDescription; - properties = new HashMap(); - subNodes = new HashMap(); - } - -// ConfigNodeBuilder helpers: - - private String makeSubNodePath(String aSubNode) { - if (path!=null && path.length()>0) - return path+"/"+aSubNode; - else - return aSubNode; - } - - private String makePropertyPath(String aProperty) { - if (path!=null && path.length()>0) - return path+"/"+aProperty; - else - return aProperty; - } - - public ConfigNodeBuilder mimicSubNode(String aName, String aLocationDescription) { - ConfigNodeBuilder result = new ConfigSimpleNode(makeSubNodePath(aName), aLocationDescription); - - return result; - } - -// ConfigNodeBuilder methods: - - public ConfigNodeBuilder makeSubNode(String aName, String aLocationDescription) { - if (subNodes.containsKey(aName)) { - return (ConfigNodeBuilder) subNodes.get(aName); - } - else { - ConfigNodeBuilder result = mimicSubNode(aName, aLocationDescription); - subNodes.put(aName, result); - - return result; - } - } - - public void addProperty(String aName, String aValue, String anUnexpandedValue, String aLocationDescription) { - properties.put(aName, new property(aValue, anUnexpandedValue, aLocationDescription, makePropertyPath(aName))); - } - -// ConfigNode helpers - - public boolean hasProperty(String aPropertyName) { - return properties.containsKey(aPropertyName); - } - - public property getProperty(String aPropertyName) { - return (property) properties.get(aPropertyName); - } - - private property getRequiredProperty(String aPropertyName) throws ConfigMissingPropertyException { - if (!hasProperty(aPropertyName)) { - throw new ConfigMissingPropertyException("required property \""+aPropertyName+"\" not found", getLocationDescription()); - } - - return getProperty(aPropertyName); - } - - -// ConfigNode methods: - - public String getLocationDescription() { - return getPath()+" ("+locationDescription+")"; - }; - - public String getPath() { - return path; - }; - - - public ConfigNode getSubNode(String aSubNodeName) { - if (subNodes.containsKey(aSubNodeName)) { - return (ConfigNode) subNodes.get(aSubNodeName); - } - else - { - return (ConfigNode) mimicSubNode(aSubNodeName, locationDescription); - } - } - - public Boolean getRequiredBooleanProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { - return getRequiredProperty(aPropertyName).interpretAsBoolean(); - } - - public Integer getRequiredIntegerProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { - return getRequiredProperty(aPropertyName).interpretAsInteger(); - } - - public String getRequiredStringProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { - return getRequiredProperty(aPropertyName).interpretAsString(); - } - - public Double getRequiredDoubleProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { - return getRequiredProperty(aPropertyName).interpretAsDouble(); - } - - - public Boolean getOptionalBooleanProperty(String aPropertyName, Boolean aDefaultValue) throws ConfigInvalidPropertyTypeException { - if (!hasProperty(aPropertyName)) { - return aDefaultValue; - } - else { - return getProperty(aPropertyName).interpretAsBoolean(); - } - } - - public Integer getOptionalIntegerProperty(String aPropertyName, Integer aDefaultValue) throws ConfigInvalidPropertyTypeException { - if (!hasProperty(aPropertyName)) { - return aDefaultValue; - } - else { - return getProperty(aPropertyName).interpretAsInteger(); - } - } - - public String getOptionalStringProperty(String aPropertyName, String aDefaultValue) throws ConfigInvalidPropertyTypeException { - if (!hasProperty(aPropertyName)) { - return aDefaultValue; - } - else { - return getProperty(aPropertyName).interpretAsString(); - } - } - - public Double getOptionalDoubleProperty(String aPropertyName, Double aDefaultValue) throws ConfigInvalidPropertyTypeException { - if (!hasProperty(aPropertyName)) { - return aDefaultValue; - } - else { - return getProperty(aPropertyName).interpretAsDouble(); - } - } - -// property helper class - - private class property { - private String value; - private String unexpandedValue; - private String path; - private String locationDescription; - - public property( String aValue, String anUnexpandedValue, String aLocationDescription, String aPath ) { - value = aValue; - unexpandedValue = anUnexpandedValue; - locationDescription = aLocationDescription; - path = aPath; - } - - public String getValue() { - return value; - } - - public String getUnexpandedValue() { - return unexpandedValue; - } - - public String getPath() { - return path; - } - - public String getLocationDescription() { - return getPath()+" ("+locationDescription+")"; - } - - public String getValueDescription() { - return "\""+value+"\" (\""+unexpandedValue+"\")"; - } - - public Boolean interpretAsBoolean() throws ConfigInvalidPropertyTypeException { - if (value.equals("1")) - return Boolean.TRUE; - else if (value.equals("0")) - return Boolean.FALSE; - else - throw new ConfigInvalidPropertyTypeException(getValueDescription() + " is not a boolean", getLocationDescription()); - } - - public String interpretAsString() throws ConfigInvalidPropertyTypeException { - return value; - } - - public Integer interpretAsInteger() throws ConfigInvalidPropertyTypeException { - try { - return Integer.valueOf(value); - } - catch (Throwable e) { - throw new ConfigInvalidPropertyTypeException("\""+value+"\" (\""+unexpandedValue+"\") is not an integer", getLocationDescription()); - } - } - - public Double interpretAsDouble() throws ConfigInvalidPropertyTypeException { - try { - return Double.valueOf(value); - } - catch (Throwable e) { - throw new ConfigInvalidPropertyTypeException("\""+value+"\" (\""+unexpandedValue+"\") is not a double", getLocationDescription()); - } - } - } -} - - + +public class ConfigSimpleNode implements ConfigNode, ConfigNodeBuilder { + private Map properties; + private Map subNodes; + private String locationDescription; + private String path; + + public ConfigSimpleNode() { + this("", ""); + } + + public ConfigSimpleNode(String aLocationDescription) { + this("", aLocationDescription); + } + + public ConfigSimpleNode(String aPath, String aLocationDescription) { + super(); + + path = aPath; + locationDescription = aLocationDescription; + properties = new HashMap(); + subNodes = new HashMap(); + } + + // ConfigNodeBuilder helpers: + private String makeSubNodePath(String aSubNode) { + if ((path != null) && (path.length() > 0)) { + return path + "/" + aSubNode; + } else { + return aSubNode; + } + } + + private String makePropertyPath(String aProperty) { + if ((path != null) && (path.length() > 0)) { + return path + "/" + aProperty; + } else { + return aProperty; + } + } + + public ConfigNodeBuilder mimicSubNode(String aName, + String aLocationDescription) { + ConfigNodeBuilder result = + new ConfigSimpleNode(makeSubNodePath(aName), aLocationDescription); + + return result; + } + + // ConfigNodeBuilder methods: + public ConfigNodeBuilder makeSubNode(String aName, String aLocationDescription) { + if (subNodes.containsKey(aName)) { + return (ConfigNodeBuilder) subNodes.get(aName); + } else { + ConfigNodeBuilder result = mimicSubNode(aName, aLocationDescription); + subNodes.put(aName, result); + + return result; + } + } + + public void addProperty(String aName, String aValue, + String anUnexpandedValue, String aLocationDescription) { + properties.put(aName, + new property(aValue, anUnexpandedValue, aLocationDescription, + makePropertyPath(aName))); + } + + // ConfigNode helpers + public boolean hasProperty(String aPropertyName) { + return properties.containsKey(aPropertyName); + } + + public property getProperty(String aPropertyName) { + return (property) properties.get(aPropertyName); + } + + private property getRequiredProperty(String aPropertyName) + throws ConfigMissingPropertyException { + if (!hasProperty(aPropertyName)) { + throw new ConfigMissingPropertyException("required property \"" + + aPropertyName + "\" not found", getLocationDescription()); + } + + return getProperty(aPropertyName); + } + + // ConfigNode methods: + public String getLocationDescription() { + return getPath() + " (" + locationDescription + ")"; + } + + public String getPath() { + return path; + } + + public ConfigNode getSubNode(String aSubNodeName) { + if (subNodes.containsKey(aSubNodeName)) { + return (ConfigNode) subNodes.get(aSubNodeName); + } else { + return (ConfigNode) mimicSubNode(aSubNodeName, locationDescription); + } + } + + public Boolean getRequiredBooleanProperty(String aPropertyName) + throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { + return getRequiredProperty(aPropertyName).interpretAsBoolean(); + } + + public Integer getRequiredIntegerProperty(String aPropertyName) + throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { + return getRequiredProperty(aPropertyName).interpretAsInteger(); + } + + public String getRequiredStringProperty(String aPropertyName) + throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { + return getRequiredProperty(aPropertyName).interpretAsString(); + } + + public Double getRequiredDoubleProperty(String aPropertyName) + throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException { + return getRequiredProperty(aPropertyName).interpretAsDouble(); + } + + public Boolean getOptionalBooleanProperty(String aPropertyName, + Boolean aDefaultValue) throws ConfigInvalidPropertyTypeException { + if (!hasProperty(aPropertyName)) { + return aDefaultValue; + } else { + return getProperty(aPropertyName).interpretAsBoolean(); + } + } + + public Integer getOptionalIntegerProperty(String aPropertyName, + Integer aDefaultValue) throws ConfigInvalidPropertyTypeException { + if (!hasProperty(aPropertyName)) { + return aDefaultValue; + } else { + return getProperty(aPropertyName).interpretAsInteger(); + } + } + + public String getOptionalStringProperty(String aPropertyName, + String aDefaultValue) throws ConfigInvalidPropertyTypeException { + if (!hasProperty(aPropertyName)) { + return aDefaultValue; + } else { + return getProperty(aPropertyName).interpretAsString(); + } + } + + public Double getOptionalDoubleProperty(String aPropertyName, + Double aDefaultValue) throws ConfigInvalidPropertyTypeException { + if (!hasProperty(aPropertyName)) { + return aDefaultValue; + } else { + return getProperty(aPropertyName).interpretAsDouble(); + } + } + + // property helper class + private class property { + private String value; + private String unexpandedValue; + private String path; + private String locationDescription; + + public property(String aValue, String anUnexpandedValue, + String aLocationDescription, String aPath) { + value = aValue; + unexpandedValue = anUnexpandedValue; + locationDescription = aLocationDescription; + path = aPath; + } + + public String getValue() { + return value; + } + + public String getUnexpandedValue() { + return unexpandedValue; + } + + public String getPath() { + return path; + } + + public String getLocationDescription() { + return getPath() + " (" + locationDescription + ")"; + } + + public String getValueDescription() { + return "\"" + value + "\" (\"" + unexpandedValue + "\")"; + } + + public Boolean interpretAsBoolean() + throws ConfigInvalidPropertyTypeException { + if (value.equals("1")) { + return Boolean.TRUE; + } else if (value.equals("0")) { + return Boolean.FALSE; + } else { + throw new ConfigInvalidPropertyTypeException(getValueDescription() + + " is not a boolean", getLocationDescription()); + } + } + + public String interpretAsString() throws ConfigInvalidPropertyTypeException { + return value; + } + + public Integer interpretAsInteger() + throws ConfigInvalidPropertyTypeException { + try { + return Integer.valueOf(value); + } catch (Throwable e) { + throw new ConfigInvalidPropertyTypeException("\"" + value + "\" (\"" + + unexpandedValue + "\") is not an integer", getLocationDescription()); + } + } + + public Double interpretAsDouble() throws ConfigInvalidPropertyTypeException { + try { + return Double.valueOf(value); + } catch (Throwable e) { + throw new ConfigInvalidPropertyTypeException("\"" + value + "\" (\"" + + unexpandedValue + "\") is not a double", getLocationDescription()); + } + } + } +} diff --git a/source/mir/config/MirConfiguration.java b/source/mir/config/MirConfiguration.java index 769e5943..022b951c 100755 --- a/source/mir/config/MirConfiguration.java +++ b/source/mir/config/MirConfiguration.java @@ -28,33 +28,32 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config; -package mir.config; - -//import java.net.*; -//import java.io.*; -//import java.util.*; -//import java.lang.*; - + +//import java.net.*; +//import java.io.*; +//import java.util.*; +//import java.lang.*; import mir.config.exceptions.ConfigFailure; - -public class MirConfiguration { - private ConfigNode rootNode; - - public MirConfiguration(ConfigNode aRootNode) { - super(); - rootNode = aRootNode; - } - - public MirConfiguration(String aFileName) throws ConfigFailure { - super(); - rootNode = new ConfigSimpleNode(); - - (new ConfigReader()).parseFile(aFileName,(ConfigNodeBuilder) rootNode); - } - - public ConfigNode getRootNode() { - return rootNode; - } -} - + + +public class MirConfiguration { + private ConfigNode rootNode; + + public MirConfiguration(ConfigNode aRootNode) { + super(); + rootNode = aRootNode; + } + + public MirConfiguration(String aFileName) throws ConfigFailure { + super(); + rootNode = new ConfigSimpleNode(); + + (new ConfigReader()).parseFile(aFileName, (ConfigNodeBuilder) rootNode); + } + + public ConfigNode getRootNode() { + return rootNode; + } +} diff --git a/source/mir/config/MirPropertiesConfiguration.java b/source/mir/config/MirPropertiesConfiguration.java index 54415450..50196e87 100755 --- a/source/mir/config/MirPropertiesConfiguration.java +++ b/source/mir/config/MirPropertiesConfiguration.java @@ -28,23 +28,23 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ - package mir.config; +import multex.Exc; +import multex.Failure; + +import org.apache.commons.configuration.PropertiesConfiguration; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; + import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.ServletContext; -import multex.Exc; -import multex.Failure; - -import org.apache.commons.configuration.PropertiesConfiguration; - /** * @author idefix @@ -53,30 +53,34 @@ public class MirPropertiesConfiguration extends PropertiesConfiguration { private static MirPropertiesConfiguration instance; private static ServletContext context; private static String contextPath; - - /** - * Constructor for MirPropertiesConfiguration. - */ - private MirPropertiesConfiguration(ServletContext ctx, String ctxPath) - throws IOException { - super(ctx.getRealPath("/WEB-INF/etc/") + "/config.properties", - ctx.getRealPath("/WEB-INF/etc/") + "/default.properties"); - this.addProperty("Home", ctx.getRealPath("/WEB-INF/")+"/"); + + /** + * Constructor for MirPropertiesConfiguration. + */ + private MirPropertiesConfiguration(ServletContext ctx, String ctxPath) + throws IOException { + super(ctx.getRealPath("/WEB-INF/etc/") + "/config.properties", + ctx.getRealPath("/WEB-INF/etc/") + "/default.properties"); + this.addProperty("Home", ctx.getRealPath("/WEB-INF/") + "/"); this.addProperty("RootUri", ctxPath); - } + } public static synchronized MirPropertiesConfiguration instance() - throws PropertiesConfigExc { - if(instance == null){ - if(context == null || contextPath == null || contextPath.length() == 0){ - throw new MirPropertiesConfiguration.PropertiesConfigExc("Context was not set"); + throws PropertiesConfigExc { + if (instance == null) { + if ((context == null) || (contextPath == null) || + (contextPath.length() == 0)) { + throw new MirPropertiesConfiguration.PropertiesConfigExc( + "Context was not set"); } + try { - instance = new MirPropertiesConfiguration(context,contextPath); + instance = new MirPropertiesConfiguration(context, contextPath); } catch (IOException e) { e.printStackTrace(); - } + } } + return instance; } @@ -87,7 +91,7 @@ public class MirPropertiesConfiguration extends PropertiesConfiguration { public static void setContext(ServletContext context) { MirPropertiesConfiguration.context = context; } - + /** * Sets the contextPath. * @param contextPath The contextPath to set @@ -95,18 +99,19 @@ public class MirPropertiesConfiguration extends PropertiesConfiguration { public static void setContextPath(String contextPath) { MirPropertiesConfiguration.contextPath = contextPath; } - - public Map allSettings(){ - Iterator iterator = this.getKeys(); - Map returnMap = new HashMap(); - while(iterator.hasNext()){ - String key = (String)iterator.next(); - returnMap.put(key,this.getProperty(key)); - } + + public Map allSettings() { + Iterator iterator = this.getKeys(); + Map returnMap = new HashMap(); + + while (iterator.hasNext()) { + String key = (String) iterator.next(); + returnMap.put(key, this.getProperty(key)); + } + return returnMap; } - /** * Returns the context. * @return ServletContext @@ -114,40 +119,43 @@ public class MirPropertiesConfiguration extends PropertiesConfiguration { public static ServletContext getContext() { return context; } - - public String getStringWithHome(String key){ - String returnString = getString(key); - if(returnString == null){ - returnString = new String(); - } - return getString("Home") + returnString; - } - - public File getFile(String key) throws FileNotFoundException{ - String path = getStringWithHome(key); - File returnFile = new File(path); - if(returnFile.exists()){ - return returnFile; - } else { - throw new FileNotFoundException(); - } - } - + + public String getStringWithHome(String key) { + String returnString = getString(key); + + if (returnString == null) { + returnString = new String(); + } + + return getString("Home") + returnString; + } + + public File getFile(String key) throws FileNotFoundException { + String path = getStringWithHome(key); + File returnFile = new File(path); + + if (returnFile.exists()) { + return returnFile; + } else { + throw new FileNotFoundException(); + } + } + /** * @see org.apache.commons.configuration.Configuration#getString(java.lang.String) */ public String getString(String key) { - if(super.getString(key) == null){ + if (super.getString(key) == null) { return new String(); } + return super.getString(key); } - + /** * @author idefix */ public static class PropertiesConfigExc extends Exc { - /** * Constructor for PropertiesConfigExc. * @param arg0 @@ -161,14 +169,12 @@ public class MirPropertiesConfiguration extends PropertiesConfiguration { * @author idefix */ public static class PropertiesConfigFailure extends Failure { - /** * Constructor for PropertiesConfigExc. * @param arg0 */ public PropertiesConfigFailure(String msg, Throwable cause) { - super(msg,cause); + super(msg, cause); } } - } diff --git a/source/mir/config/exceptions/ConfigDefineNotKnownException.java b/source/mir/config/exceptions/ConfigDefineNotKnownException.java index cfd99b02..d09ef93f 100755 --- a/source/mir/config/exceptions/ConfigDefineNotKnownException.java +++ b/source/mir/config/exceptions/ConfigDefineNotKnownException.java @@ -28,11 +28,10 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config.exceptions; -package mir.config.exceptions; - -public class ConfigDefineNotKnownException extends ConfigFailure { - public ConfigDefineNotKnownException(String aMessage, String aLocation) { - super (aMessage, aLocation); - } -} +public class ConfigDefineNotKnownException extends ConfigFailure { + public ConfigDefineNotKnownException(String aMessage, String aLocation) { + super(aMessage, aLocation); + } +} diff --git a/source/mir/config/exceptions/ConfigFailure.java b/source/mir/config/exceptions/ConfigFailure.java index f1576501..8fa8eba7 100755 --- a/source/mir/config/exceptions/ConfigFailure.java +++ b/source/mir/config/exceptions/ConfigFailure.java @@ -28,27 +28,29 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ - package mir.config.exceptions; import multex.Failure; + public class ConfigFailure extends Failure { private String locationDescription; private Throwable cause; - public ConfigFailure (String aMessage, Throwable aCause, String aLocationDescription) { - super ("Configuration error at "+aLocationDescription+": "+aMessage, aCause); + public ConfigFailure(String aMessage, Throwable aCause, + String aLocationDescription) { + super("Configuration error at " + aLocationDescription + ": " + aMessage, + aCause); locationDescription = aLocationDescription; cause = aCause; } - public ConfigFailure (String aMessage, String aLocationDescription) { - this (aMessage, (Throwable) null, aLocationDescription); + public ConfigFailure(String aMessage, String aLocationDescription) { + this(aMessage, (Throwable) null, aLocationDescription); } - public ConfigFailure (String aMessage) { - this (aMessage, (Throwable) null, "?"); + public ConfigFailure(String aMessage) { + this(aMessage, (Throwable) null, "?"); } } diff --git a/source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java b/source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java index 6a27a9c3..8bdba124 100755 --- a/source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java +++ b/source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java @@ -28,11 +28,10 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config.exceptions; -package mir.config.exceptions; - -public class ConfigInvalidPropertyTypeException extends ConfigFailure { - public ConfigInvalidPropertyTypeException(String aMessage, String aLocation) { - super (aMessage, aLocation); - } -} +public class ConfigInvalidPropertyTypeException extends ConfigFailure { + public ConfigInvalidPropertyTypeException(String aMessage, String aLocation) { + super(aMessage, aLocation); + } +} diff --git a/source/mir/config/exceptions/ConfigMissingPropertyException.java b/source/mir/config/exceptions/ConfigMissingPropertyException.java index 54debe56..2ac99e59 100755 --- a/source/mir/config/exceptions/ConfigMissingPropertyException.java +++ b/source/mir/config/exceptions/ConfigMissingPropertyException.java @@ -28,11 +28,10 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ +package mir.config.exceptions; -package mir.config.exceptions; - -public class ConfigMissingPropertyException extends ConfigFailure { - public ConfigMissingPropertyException(String aMessage, String aLocation) { - super (aMessage, aLocation); - } -} +public class ConfigMissingPropertyException extends ConfigFailure { + public ConfigMissingPropertyException(String aMessage, String aLocation) { + super(aMessage, aLocation); + } +} diff --git a/source/mir/storage/Database.java b/source/mir/storage/Database.java index c5d8cf44..e19deef1 100755 --- a/source/mir/storage/Database.java +++ b/source/mir/storage/Database.java @@ -1,1311 +1,1473 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ - -package mir.storage; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; - -import mir.config.MirPropertiesConfiguration; -import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; -import mir.entity.Entity; -import mir.entity.EntityList; -import mir.entity.StorableObjectEntity; -import mir.misc.HTMLTemplateProcessor; -import mir.misc.Logfile; -import mir.misc.StringUtil; -import mir.storage.store.ObjectStore; -import mir.storage.store.StorableObject; -import mir.storage.store.StoreContainerType; -import mir.storage.store.StoreIdentifier; -import mir.storage.store.StoreUtil; -import mir.util.JDBCStringRoutines; - -import com.codestudio.util.SQLManager; - -import freemarker.template.SimpleHash; -import freemarker.template.SimpleList; - - -/** - * Diese Klasse implementiert die Zugriffsschicht auf die Datenbank. - * Alle Projektspezifischen Datenbankklassen erben von dieser Klasse. - * In den Unterklassen wird im Minimalfall nur die Tabelle angegeben. - * Im Konfigurationsfile findet sich eine Verweis auf den verwendeten - * Treiber, Host, User und Passwort, ueber den der Zugriff auf die - * Datenbank erfolgt. - * - * @version $Id: Database.java,v 1.31 2003/01/25 17:45:19 idfx Exp $ - * @author rk - * - */ -public class Database implements StorageObject { - - protected MirPropertiesConfiguration configuration; - protected String theTable; - protected String theCoreTable=null; - protected String thePKeyName="id"; - protected int thePKeyType, thePKeyIndex; - protected boolean evaluatedMetaData=false; - protected ArrayList metadataFields,metadataLabels, - metadataNotNullFields; - protected int[] metadataTypes; - protected Class theEntityClass; - protected StorageObject myselfDatabase; - protected SimpleList popupCache=null; - protected boolean hasPopupCache = false; - protected SimpleHash hashCache=null; - protected boolean hasTimestamp=true; - private String database_driver, database_url; - private int defaultLimit; - protected DatabaseAdaptor theAdaptor; - protected Logfile theLog; - private static Class GENERIC_ENTITY_CLASS=null, - STORABLE_OBJECT_ENTITY_CLASS=null; - private static SimpleHash POPUP_EMTYLINE=new SimpleHash(); - protected static final ObjectStore o_store=ObjectStore.getInstance(); - private SimpleDateFormat _dateFormatterOut = - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private SimpleDateFormat _dateFormatterIn = - new SimpleDateFormat("yyyy-MM-dd HH:mm"); - private Calendar _cal = new GregorianCalendar(); - - private static final int _millisPerHour = 60 * 60 * 1000; - private static final int _millisPerMinute = 60 * 1000; - - static { - // always same object saves a little space - POPUP_EMTYLINE.put("key", ""); POPUP_EMTYLINE.put("value", "--"); - try { - GENERIC_ENTITY_CLASS = Class.forName("mir.entity.StorableObjectEntity"); - STORABLE_OBJECT_ENTITY_CLASS = Class.forName("mir.entity.StorableObjectEntity"); - } - catch (Exception e) { - System.err.println("FATAL: Database.java could not initialize" + e.getMessage()); - } - } - - - /** - * Kontruktor bekommt den Filenamen des Konfigurationsfiles ?bergeben. - * Aus diesem file werden Database.Logfile, - * Database.Username,Database.Password, - * Database.Host und Database.Adaptor - * ausgelesen und ein Broker f?r die Verbindugen zur Datenbank - * erzeugt. - * - * @param String confFilename Dateiname der Konfigurationsdatei - */ - public Database() throws StorageObjectFailure { - try { - configuration = MirPropertiesConfiguration.instance(); - } catch (PropertiesConfigExc e) { - throw new StorageObjectFailure(e); - } - theLog = Logfile.getInstance(configuration.getStringWithHome("Database.Logfile")); - String theAdaptorName=configuration.getString("Database.Adaptor"); - defaultLimit = Integer.parseInt(configuration.getString("Database.Limit")); - try { - theEntityClass = GENERIC_ENTITY_CLASS; - theAdaptor = (DatabaseAdaptor)Class.forName(theAdaptorName).newInstance(); - } catch (Exception e){ - theLog.printError("Error in Database() constructor with "+ - theAdaptorName + " -- " +e.getMessage()); - throw new StorageObjectFailure("Error in Database() constructor.",e); - } - } - - /** - * Liefert die Entity-Klasse zur?ck, in der eine Datenbankzeile gewrappt - * wird. Wird die Entity-Klasse durch die erbende Klasse nicht ?berschrieben, - * wird eine mir.entity.GenericEntity erzeugt. - * - * @return Class-Objekt der Entity - */ - public java.lang.Class getEntityClass () { - return theEntityClass; - } - - /** - * Liefert die Standardbeschr?nkung von select-Statements zur?ck, also - * wieviel Datens?tze per Default selektiert werden. - * - * @return Standard-Anzahl der Datens?tze - */ - public int getLimit () { - return defaultLimit; - } - - /** - * Liefert den Namen des Primary-Keys zur?ck. Wird die Variable nicht von - * der erbenden Klasse ?berschrieben, so ist der Wert PKEY - * @return Name des Primary-Keys - */ - public String getIdName () { - return thePKeyName; - } - - /** - * Liefert den Namen der Tabelle, auf das sich das Datenbankobjekt bezieht. - * - * @return Name der Tabelle - */ - public String getTableName () { - return theTable; - } - - /* - * Dient dazu vererbte Tabellen bei objectrelationalen DBMS - * zu speichern, wenn die id einer Tabelle in der parenttabelle verwaltet - * wird. - * @return liefert theCoreTabel als String zurueck, wenn gesetzt, sonst - * the Table - */ - - public String getCoreTable(){ - if (theCoreTable!=null) return theCoreTable; - else return theTable; - } - - /** - * Liefert Feldtypen der Felder der Tabelle zurueck (s.a. java.sql.Types) - * @return int-Array mit den Typen der Felder - * @exception StorageObjectException - */ - public int[] getTypes () throws StorageObjectFailure { - if (metadataTypes == null) - get_meta_data(); - return metadataTypes; - } - - /** - * Liefert eine Liste der Labels der Tabellenfelder - * @return ArrayListe mit Labeln - * @exception StorageObjectException - */ - public ArrayList getLabels () throws StorageObjectFailure { - if (metadataLabels == null) - get_meta_data(); - return metadataLabels; - } - - /** - * Liefert eine Liste der Felder der Tabelle - * @return ArrayList mit Feldern - * @exception StorageObjectException - */ - public ArrayList getFields () throws StorageObjectFailure { - if (metadataFields == null) - get_meta_data(); - return metadataFields; - } - - - /* - * Gets value out of ResultSet according to type and converts to String - * @param inValue Wert aus ResultSet. - * @param aType Datenbanktyp. - * @return liefert den Wert als String zurueck. Wenn keine Umwandlung moeglich - * dann /unsupported value/ - */ - private String getValueAsString (ResultSet rs, int valueIndex, int aType) - throws StorageObjectFailure { - String outValue = null; - if (rs != null) { - try { - switch (aType) { - case java.sql.Types.BIT: - outValue = (rs.getBoolean(valueIndex) == true) ? "1" : "0"; - break; - case java.sql.Types.INTEGER:case java.sql.Types.SMALLINT:case java.sql.Types.TINYINT:case java.sql.Types.BIGINT: - int out = rs.getInt(valueIndex); - if (!rs.wasNull()) - outValue = new Integer(out).toString(); - break; - case java.sql.Types.NUMERIC: - /** @todo Numeric can be float or double depending upon - * metadata.getScale() / especially with oracle */ - long outl = rs.getLong(valueIndex); - if (!rs.wasNull()) - outValue = new Long(outl).toString(); - break; - case java.sql.Types.REAL: - float tempf = rs.getFloat(valueIndex); - if (!rs.wasNull()) { - tempf *= 10; - tempf += 0.5; - int tempf_int = (int)tempf; - tempf = (float)tempf_int; - tempf /= 10; - outValue = "" + tempf; - outValue = outValue.replace('.', ','); - } - break; - case java.sql.Types.DOUBLE: - double tempd = rs.getDouble(valueIndex); - if (!rs.wasNull()) { - tempd *= 10; - tempd += 0.5; - int tempd_int = (int)tempd; - tempd = (double)tempd_int; - tempd /= 10; - outValue = "" + tempd; - outValue = outValue.replace('.', ','); - } - break; - case java.sql.Types.CHAR:case java.sql.Types.VARCHAR:case java.sql.Types.LONGVARCHAR: - outValue = rs.getString(valueIndex); - break; - case java.sql.Types.LONGVARBINARY: - outValue = rs.getString(valueIndex); - break; - case java.sql.Types.TIMESTAMP: - // it's important to use Timestamp here as getting it - // as a string is undefined and is only there for debugging - // according to the API. we can make it a string through formatting. - // -mh - Timestamp timestamp = (rs.getTimestamp(valueIndex)); - if(!rs.wasNull()) { - java.util.Date date = new java.util.Date(timestamp.getTime()); - outValue = _dateFormatterOut.format(date); - _cal.setTime(date); - int offset = _cal.get(Calendar.ZONE_OFFSET)+ - _cal.get(Calendar.DST_OFFSET); - String tzOffset = StringUtil.zeroPaddingNumber( - offset/_millisPerHour,2,2); - outValue = outValue+"+"+tzOffset; - } - break; - default: - outValue = ""; - theLog.printWarning("Unsupported Datatype: at " + valueIndex + - " (" + aType + ")"); - } - } catch (SQLException e) { - throw new StorageObjectFailure("Could not get Value out of Resultset -- ",e); - } - } - return outValue; - } - - /* - * select-Operator um einen Datensatz zu bekommen. - * @param id Primaerschluessel des Datensatzes. - * @return liefert EntityObject des gefundenen Datensatzes oder null. - */ - public Entity selectById(String id) - throws StorageObjectExc { - if (id==null||id.equals("")) - throw new StorageObjectExc("id war null"); - - // ask object store for object - if ( StoreUtil.implementsStorableObject(theEntityClass) ) { - String uniqueId = id; - if ( theEntityClass.equals(StorableObjectEntity.class) ) - uniqueId+="@"+theTable; - StoreIdentifier search_sid = new StoreIdentifier(theEntityClass, uniqueId); - theLog.printDebugInfo("CACHE: (dbg) looking for sid " + search_sid.toString()); - Entity hit = (Entity)o_store.use(search_sid); - if ( hit!=null ) return hit; - } - - Statement stmt=null;Connection con=getPooledCon(); - Entity returnEntity=null; - try { - ResultSet rs; - /** @todo better prepared statement */ - String selectSql = "select * from " + theTable + " where " + thePKeyName + "=" + id; - stmt = con.createStatement(); - rs = executeSql(stmt, selectSql); - if (rs != null) { - if (evaluatedMetaData==false) evalMetaData(rs.getMetaData()); - if (rs.next()) - returnEntity = makeEntityFromResultSet(rs); - else theLog.printDebugInfo("Keine daten fuer id: " + id + "in Tabelle" + theTable); - rs.close(); - } - else { - theLog.printDebugInfo("No Data for Id " + id + " in Table " + theTable); - } - } - catch (SQLException sqe){ - throwSQLException(sqe,"selectById"); return null; - } - catch (NumberFormatException e) { - theLog.printError("ID ist keine Zahl: " + id); - } - finally { freeConnection(con,stmt); } - - /** @todo OS: Entity should be saved in ostore */ - return returnEntity; - } - - - /** - * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. - * @param key Datenbankfeld der Bedingung. - * @param value Wert die der key anehmen muss. - * @return EntityList mit den gematchten Entities - */ - public EntityList selectByFieldValue(String aField, String aValue) - throws StorageObjectFailure - { - return selectByFieldValue(aField, aValue, 0); - } - - /** - * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. - * @param key Datenbankfeld der Bedingung. - * @param value Wert die der key anehmen muss. - * @param offset Gibt an ab welchem Datensatz angezeigt werden soll. - * @return EntityList mit den gematchten Entities - */ - public EntityList selectByFieldValue(String aField, String aValue, int offset) - throws StorageObjectFailure - { - return selectByWhereClause(aField + "=" + aValue, offset); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. - * Also offset wird der erste Datensatz genommen. - * - * @param wc where-Clause - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - public EntityList selectByWhereClause(String where) - throws StorageObjectFailure - { - return selectByWhereClause(where, 0); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. - * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. - * - * @param wc where-Clause - * @param offset ab welchem Datensatz. - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - public EntityList selectByWhereClause(String whereClause, int offset) - throws StorageObjectFailure - { - return selectByWhereClause(whereClause, null, offset); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. - * Also offset wird der erste Datensatz genommen. - * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. - * - * @param wc where-Clause - * @param ob orderBy-Clause - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - - public EntityList selectByWhereClause(String where, String order) - throws StorageObjectFailure { - return selectByWhereClause(where, order, 0); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. - * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. - * - * @param wc where-Clause - * @param ob orderBy-Clause - * @param offset ab welchem Datensatz - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - - public EntityList selectByWhereClause(String whereClause, String orderBy, int offset) - throws StorageObjectFailure { - return selectByWhereClause(whereClause, orderBy, offset, defaultLimit); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. - * @param wc where-Clause - * @param ob orderBy-Clause - * @param offset ab welchem Datensatz - * @param limit wieviele Datens?tze - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - - public EntityList selectByWhereClause(String wc, String ob, int offset, - int limit) throws - StorageObjectFailure { - - // check o_store for entitylist - if (StoreUtil.implementsStorableObject(theEntityClass)) { - StoreIdentifier search_sid = - new StoreIdentifier(theEntityClass, - StoreContainerType.STOC_TYPE_ENTITYLIST, - StoreUtil.getEntityListUniqueIdentifierFor( - theTable, wc, ob, offset, limit)); - EntityList hit = (EntityList) o_store.use(search_sid); - if (hit != null) { - theLog.printDebugInfo("CACHE (hit): " + search_sid.toString()); - return hit; - } - } - - // local - EntityList theReturnList = null; - Connection con = null; - Statement stmt = null; - ResultSet rs; - int offsetCount = 0, count = 0; - - // build sql-statement - - /** @todo count sql string should only be assembled if we really count - * see below at the end of method //rk */ - - if (wc != null && wc.length() == 0) { - wc = null; - } - StringBuffer countSql = new StringBuffer("select count(*) from ").append( - theTable); - StringBuffer selectSql = new StringBuffer("select * from ").append(theTable); - if (wc != null) { - selectSql.append(" where ").append(wc); - countSql.append(" where ").append(wc); - } - if (ob != null && ! (ob.length() == 0)) { - selectSql.append(" order by ").append(ob); - } - if (theAdaptor.hasLimit()) { - if (limit > -1 && offset > -1) { - selectSql.append(" LIMIT ").append(limit).append(" OFFSET ").append(offset); - } - } - - // execute sql - try { - con = getPooledCon(); - stmt = con.createStatement(); - - // selecting... - rs = executeSql(stmt, selectSql.toString()); - if (rs != null) { - if (!evaluatedMetaData) - evalMetaData(rs.getMetaData()); - - theReturnList = new EntityList(); - Entity theResultEntity; - while (rs.next()) { - theResultEntity = makeEntityFromResultSet(rs); - theReturnList.add(theResultEntity); - offsetCount++; - } - rs.close(); - } - - // making entitylist infos - if (! (theAdaptor.hasLimit())) - count = offsetCount; - - if (theReturnList != null) { - // now we decide if we have to know an overall count... - count = offsetCount; - if (limit > -1 && offset > -1) { - if (offsetCount == limit) { - /** @todo counting should be deffered to entitylist - * getSize() should be used */ - rs = executeSql(stmt, countSql.toString()); - if (rs != null) { - if (rs.next()) - count = rs.getInt(1); - rs.close(); - } - else - theLog.printError("Could not count: " + countSql); - } - } - theReturnList.setCount(count); - theReturnList.setOffset(offset); - theReturnList.setWhere(wc); - theReturnList.setOrder(ob); - theReturnList.setStorage(this); - theReturnList.setLimit(limit); - if (offset >= limit) - theReturnList.setPrevBatch(offset - limit); - if (offset + offsetCount < count) - theReturnList.setNextBatch(offset + limit); - if (StoreUtil.implementsStorableObject(theEntityClass)) { - StoreIdentifier sid = theReturnList.getStoreIdentifier(); - theLog.printDebugInfo("CACHE (add): " + sid.toString()); - o_store.add(sid); - } - } - } - catch (SQLException sqe) { - throwSQLException(sqe, "selectByWhereClause"); - } - finally { - try { - if (con != null) - freeConnection(con, stmt); - } - catch (Throwable t) { - } - - } - - return theReturnList; - } - - - /** - * Bastelt aus einer Zeile der Datenbank ein EntityObjekt. - * - * @param rs Das ResultSetObjekt. - * @return Entity Die Entity. - */ - private Entity makeEntityFromResultSet (ResultSet rs) - throws StorageObjectFailure - { - /** @todo OS: get Pkey from ResultSet and consult ObjectStore */ - HashMap theResultHash = new HashMap(); - String theResult = null; - int theType; - Entity returnEntity = null; - try { - int size = metadataFields.size(); - for (int i = 0; i < size; i++) { - // alle durchlaufen bis nix mehr da - - theType = metadataTypes[i]; - if (theType == java.sql.Types.LONGVARBINARY) { - InputStreamReader is = (InputStreamReader)rs.getCharacterStream(i + 1); - if (is != null) { - char[] data = new char[32768]; - StringBuffer theResultString = new StringBuffer(); - int len; - while ((len = is.read(data)) > 0) { - theResultString.append(data, 0, len); - } - is.close(); - theResult = theResultString.toString(); - } - else { - theResult = null; - } - } - else { - theResult = getValueAsString(rs, (i + 1), theType); - } - if (theResult != null) { - theResultHash.put(metadataFields.get(i), theResult); - } - } - if (theEntityClass != null) { - returnEntity = (Entity)theEntityClass.newInstance(); - returnEntity.setValues(theResultHash); - returnEntity.setStorage(myselfDatabase); - if ( returnEntity instanceof StorableObject ) { - theLog.printDebugInfo("CACHE: ( in) " + returnEntity.getId() + " :"+theTable); - o_store.add(((StorableObject)returnEntity).getStoreIdentifier()); - } - } else { - throwStorageObjectException("Internal Error: theEntityClass not set!"); - } - } - catch (IllegalAccessException e) { - throwStorageObjectException("No access! -- " + e.getMessage()); - } - catch (IOException e) { - throwStorageObjectException("IOException! -- " + e.getMessage()); - } - catch (InstantiationException e) { - throwStorageObjectException("No Instatiation! -- " + e.getMessage()); - } - catch (SQLException sqe) { - throwSQLException(sqe, "makeEntityFromResultSet"); - return null; - } - return returnEntity; - } - - /** - * insert-Operator: f?gt eine Entity in die Tabelle ein. Eine Spalte WEBDB_CREATE - * wird automatisch mit dem aktuellen Datum gefuellt. - * - * @param theEntity - * @return der Wert des Primary-keys der eingef?gten Entity - */ - public String insert (Entity theEntity) throws StorageObjectFailure { - //cache - invalidatePopupCache(); - - // invalidating all EntityLists corresponding with theEntityClass - if ( StoreUtil.implementsStorableObject(theEntityClass) ) { - StoreContainerType stoc_type = - StoreContainerType.valueOf( theEntityClass, - StoreContainerType.STOC_TYPE_ENTITYLIST); - o_store.invalidate(stoc_type); - } - - String returnId = null; - Connection con = null; PreparedStatement pstmt = null; - - try { - ArrayList streamedInput = theEntity.streamedInput(); - StringBuffer f = new StringBuffer(); - StringBuffer v = new StringBuffer(); - String aField, aValue; - boolean firstField = true; - // make sql-string - for (int i = 0; i < getFields().size(); i++) { - aField = (String)getFields().get(i); - if (!aField.equals(thePKeyName)) { - aValue = null; - // sonderfaelle - if (aField.equals("webdb_create") || - aField.equals("webdb_lastchange")) { - aValue = "NOW()"; - } - else { - if (streamedInput != null && streamedInput.contains(aField)) { - aValue = "?"; - } - else { - if (theEntity.hasValueForField(aField)) { - aValue = "'" + JDBCStringRoutines.escapeStringLiteral((String)theEntity.getValue(aField)) + "'"; - } - } - } - // wenn Wert gegeben, dann einbauen - if (aValue != null) { - if (firstField == false) { - f.append(","); - v.append(","); - } - else { - firstField = false; - } - f.append(aField); - v.append(aValue); - } - } - } // end for - // insert into db - StringBuffer sqlBuf = new StringBuffer("insert into ").append(theTable).append("(").append(f).append(") values (").append(v).append(")"); - String sql = sqlBuf.toString(); - //theLog.printInfo("INSERT: " + sql); - con = getPooledCon(); - con.setAutoCommit(false); - pstmt = con.prepareStatement(sql); - if (streamedInput != null) { - for (int i = 0; i < streamedInput.size(); i++) { - String inputString = (String)theEntity.getValue((String)streamedInput.get(i)); - pstmt.setBytes(i + 1, inputString.getBytes()); - } - } - int ret = pstmt.executeUpdate(); - if(ret == 0){ - //insert failed - return null; - } - pstmt = con.prepareStatement(theAdaptor.getLastInsertSQL((Database)myselfDatabase)); - ResultSet rs = pstmt.executeQuery(); - rs.next(); - returnId = rs.getString(1); - theEntity.setId(returnId); - } catch (SQLException sqe) { - throwSQLException(sqe, "insert"); - } finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - ; - } - freeConnection(con, pstmt); - } - /** @todo store entity in o_store */ - return returnId; - } - - /** - * update-Operator: aktualisiert eine Entity. Eine Spalte WEBDB_LASTCHANGE - * wird automatisch mit dem aktuellen Datum gefuellt. - * - * @param theEntity - */ - public void update (Entity theEntity) throws StorageObjectFailure - { - Connection con = null; PreparedStatement pstmt = null; - /** @todo this is stupid: why do we prepare statement, when we - * throw it away afterwards. should be regular statement - * update/insert could better be one routine called save() - * that chooses to either insert or update depending if we - * have a primary key in the entity. i don't know if we - * still need the streamed input fields. // rk */ - - /** @todo extension: check if Entity did change, otherwise we don't need - * the roundtrip to the database */ - - /** invalidating corresponding entitylists in o_store*/ - if ( StoreUtil.implementsStorableObject(theEntityClass) ) { - StoreContainerType stoc_type = - StoreContainerType.valueOf( theEntityClass, - StoreContainerType.STOC_TYPE_ENTITYLIST); - o_store.invalidate(stoc_type); - } - - ArrayList streamedInput = theEntity.streamedInput(); - String id = theEntity.getId(); - String aField; - StringBuffer fv = new StringBuffer(); - boolean firstField = true; - //cache - invalidatePopupCache(); - // build sql statement - for (int i = 0; i < getFields().size(); i++) { - aField = (String)metadataFields.get(i); - // only normal cases - if (!(aField.equals(thePKeyName) || aField.equals("webdb_create") || - aField.equals("webdb_lastchange") || (streamedInput != null && streamedInput.contains(aField)))) { - if (theEntity.hasValueForField(aField)) { - if (firstField == false) { - fv.append(", "); - } - else { - firstField = false; - } - fv.append(aField).append("='").append(JDBCStringRoutines.escapeStringLiteral((String) theEntity.getValue(aField))).append("'"); - -// fv.append(aField).append("='").append(StringUtil.quote((String)theEntity.getValue(aField))).append("'"); - } - } - } - StringBuffer sql = new StringBuffer("update ").append(theTable).append(" set ").append(fv); - // exceptions - if (metadataFields.contains("webdb_lastchange")) { - sql.append(",webdb_lastchange=NOW()"); - } - // special case: the webdb_create requires the field in yyyy-mm-dd HH:mm - // format so anything extra will be ignored. -mh - if (metadataFields.contains("webdb_create") && - theEntity.hasValueForField("webdb_create")) { - // minimum of 10 (yyyy-mm-dd)... - if (theEntity.getValue("webdb_create").length() >= 10) { - String dateString = theEntity.getValue("webdb_create"); - // if only 10, then add 00:00 so it doesn't throw a ParseException - if (dateString.length() == 10) - dateString=dateString+" 00:00"; - - // TimeStamp stuff - try { - java.util.Date d = _dateFormatterIn.parse(dateString); - Timestamp tStamp = new Timestamp(d.getTime()); - sql.append(",webdb_create='"+tStamp.toString()+"'"); - } catch (ParseException e) { - throw new StorageObjectFailure(e); - } - } - } - if (streamedInput != null) { - for (int i = 0; i < streamedInput.size(); i++) { - sql.append(",").append(streamedInput.get(i)).append("=?"); - } - } - sql.append(" where id=").append(id); - //theLog.printInfo("UPDATE: " + sql); - // execute sql - try { - con = getPooledCon(); - con.setAutoCommit(false); - pstmt = con.prepareStatement(sql.toString()); - if (streamedInput != null) { - for (int i = 0; i < streamedInput.size(); i++) { - String inputString = theEntity.getValue((String)streamedInput.get(i)); - pstmt.setBytes(i + 1, inputString.getBytes()); - } - } - pstmt.executeUpdate(); - } - catch (SQLException sqe) { - throwSQLException(sqe, "update"); - } - finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - ; - } - freeConnection(con, pstmt); - } - } - - /* - * delete-Operator - * @param id des zu loeschenden Datensatzes - * @return boolean liefert true zurueck, wenn loeschen erfolgreich war. - */ - public boolean delete (String id) throws StorageObjectFailure { - - invalidatePopupCache(); - // ostore send notification - if ( StoreUtil.implementsStorableObject(theEntityClass) ) { - String uniqueId = id; - if ( theEntityClass.equals(StorableObjectEntity.class) ) - uniqueId+="@"+theTable; - theLog.printInfo("CACHE: (del) " + id); - StoreIdentifier search_sid = - new StoreIdentifier(theEntityClass, StoreContainerType.STOC_TYPE_ENTITY, uniqueId); - o_store.invalidate(search_sid); - } - - /** @todo could be prepared Statement */ - Statement stmt = null; Connection con = null; - int res = 0; - String sql="delete from "+theTable+" where "+thePKeyName+"='"+id+"'"; - //theLog.printInfo("DELETE " + sql); - try { - con = getPooledCon(); stmt = con.createStatement(); - res = stmt.executeUpdate(sql); - } - catch (SQLException sqe) { throwSQLException(sqe, "delete"); } - finally { freeConnection(con, stmt); } - - return (res > 0) ? true : false; - } - - /* noch nicht implementiert. - * @return immer false - */ - public boolean delete (EntityList theEntityList) { - invalidatePopupCache(); - return false; - } - - /** - * Diese Methode sollte ueberschrieben werden, wenn fuer die abgeleitete Database-Klasse - * eine SimpleList mit Standard-Popupdaten erzeugt werden koennen soll. - * @return null - */ - public SimpleList getPopupData () throws StorageObjectFailure { - return null; - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData (String name, boolean hasNullValue) - throws StorageObjectFailure { - return getPopupData(name, hasNullValue, null); - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @param where Schraenkt die Selektion der Datensaetze ein. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData (String name, boolean hasNullValue, String where) throws StorageObjectFailure { - return getPopupData(name, hasNullValue, where, null); - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @param where Schraenkt die Selektion der Datensaetze ein. - * @param order Gibt ein Feld als Sortierkriterium an. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData (String name, boolean hasNullValue, String where, String order) throws StorageObjectFailure { - // caching - if (hasPopupCache && popupCache != null) - return popupCache; - SimpleList simpleList = null; - Connection con = null; - Statement stmt = null; - // build sql - StringBuffer sql = new StringBuffer("select ").append(thePKeyName) - .append(",").append(name).append(" from ") - .append(theTable); - if (where != null && !(where.length() == 0)) - sql.append(" where ").append(where); - sql.append(" order by "); - if (order != null && !(order.length() == 0)) - sql.append(order); - else - sql.append(name); - // execute sql - try { - con = getPooledCon(); - } - catch (Exception e) { - throw new StorageObjectFailure(e); - } - try { - stmt = con.createStatement(); - ResultSet rs = executeSql(stmt, sql.toString()); - - if (rs != null) { - if (!evaluatedMetaData) get_meta_data(); - simpleList = new SimpleList(); - // if popup has null-selector - if (hasNullValue) simpleList.add(POPUP_EMTYLINE); - - SimpleHash popupDict; - while (rs.next()) { - popupDict = new SimpleHash(); - popupDict.put("key", getValueAsString(rs, 1, thePKeyType)); - popupDict.put("value", rs.getString(2)); - simpleList.add(popupDict); - } - rs.close(); - } - } - catch (Exception e) { - theLog.printError("getPopupData: "+e.getMessage()); - throw new StorageObjectFailure(e); - } - finally { - freeConnection(con, stmt); - } - - if (hasPopupCache) popupCache = simpleList; - return simpleList; - } - - /** - * Liefert alle Daten der Tabelle als SimpleHash zurueck. Dies wird verwandt, - * wenn in den Templates ein Lookup-Table benoetigt wird. Sollte nur bei kleinen - * Tabellen Verwendung finden. - * @return SimpleHash mit den Tabellezeilen. - */ - public SimpleHash getHashData () { - /** @todo dangerous! this should have a flag to be enabled, otherwise - * very big Hashes could be returned */ - if (hashCache == null) { - try { - hashCache = HTMLTemplateProcessor.makeSimpleHash(selectByWhereClause("", - -1)); - } - catch (StorageObjectFailure e) { - theLog.printDebugInfo(e.getMessage()); - } - } - return hashCache; - } - - /* invalidates the popupCache - */ - protected void invalidatePopupCache () { - /** @todo invalidates toooo much */ - popupCache = null; - hashCache = null; - } - - /** - * Diese Methode fuehrt den Sqlstring sql aus und timed im Logfile. - * @param stmt Statemnt - * @param sql Sql-String - * @return ResultSet - * @exception StorageObjectException - */ - public ResultSet executeSql (Statement stmt, String sql) - throws StorageObjectFailure, SQLException - { - long startTime = System.currentTimeMillis(); - ResultSet rs; - try { - rs = stmt.executeQuery(sql); - //theLog.printInfo((System.currentTimeMillis() - startTime) + "ms. for: " + sql); - } - catch (SQLException e) - { - theLog.printDebugInfo("Failed: " + (System.currentTimeMillis() - startTime) + "ms. for: "+ sql); - throw e; - } - - return rs; - } - - /** - * Fuehrt Statement stmt aus und liefert Resultset zurueck. Das SQL-Statment wird - * getimed und geloggt. - * @param stmt PreparedStatement mit der SQL-Anweisung - * @return Liefert ResultSet des Statements zurueck. - * @exception StorageObjectException, SQLException - */ - public ResultSet executeSql (PreparedStatement stmt) - throws StorageObjectFailure, SQLException { - - long startTime = (new java.util.Date()).getTime(); - ResultSet rs = stmt.executeQuery(); - theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms."); - return rs; - } - - /** - * returns the number of rows in the table - */ - public int getSize(String where) - throws SQLException,StorageObjectFailure - { - long startTime = System.currentTimeMillis(); - String sql = "SELECT Count(*) FROM "+ theTable; - if (where != null && !(where.length() == 0)) - sql = sql + " where " + where; - Connection con = null; - Statement stmt = null; - int result = 0; - - try { - con = getPooledCon(); - stmt = con.createStatement(); - ResultSet rs = executeSql(stmt,sql); - while(rs.next()){ - result = rs.getInt(1); - } - } - catch (SQLException e) { - theLog.printError(e.getMessage()); - } - finally { - freeConnection(con,stmt); - } - //theLog.printInfo(theTable + " has "+ result +" rows where " + where); - //theLog.printInfo((System.currentTimeMillis() - startTime) + "ms. for: " + sql); - return result; - } - - public int executeUpdate(Statement stmt, String sql) - throws StorageObjectFailure, SQLException - { - int rs; - long startTime = (new java.util.Date()).getTime(); - try - { - rs = stmt.executeUpdate(sql); - //theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); - } - catch (SQLException e) - { - theLog.printDebugInfo("Failed: " + (new java.util.Date().getTime() - - startTime) + "ms. for: "+ sql); - throw e; - } - return rs; - } - - public int executeUpdate(String sql) throws StorageObjectFailure, SQLException - { - int result=-1; - long startTime = (new java.util.Date()).getTime(); - Connection con=null; - PreparedStatement pstmt=null; - try { - con=getPooledCon(); - pstmt = con.prepareStatement(sql); - result = pstmt.executeUpdate(); - } - catch (Exception e) { - theLog.printDebugInfo("executeUpdate failed: "+e.getMessage()); - throw new StorageObjectFailure("executeUpdate failed",e); - } - finally { - freeConnection(con,pstmt); - } - //theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); - return result; - } - - /** - * Wertet ResultSetMetaData aus und setzt interne Daten entsprechend - * @param md ResultSetMetaData - * @exception StorageObjectException - */ - private void evalMetaData (ResultSetMetaData md) - throws StorageObjectFailure { - - this.evaluatedMetaData = true; - this.metadataFields = new ArrayList(); - this.metadataLabels = new ArrayList(); - this.metadataNotNullFields = new ArrayList(); - try { - int numFields = md.getColumnCount(); - this.metadataTypes = new int[numFields]; - String aField; - int aType; - for (int i = 1; i <= numFields; i++) { - aField = md.getColumnName(i); - metadataFields.add(aField); - metadataLabels.add(md.getColumnLabel(i)); - aType = md.getColumnType(i); - metadataTypes[i - 1] = aType; - if (aField.equals(thePKeyName)) { - thePKeyType = aType; thePKeyIndex = i; - } - if (md.isNullable(i) == ResultSetMetaData.columnNullable) { - metadataNotNullFields.add(aField); - } - } - } catch (SQLException e) { - throwSQLException(e, "evalMetaData"); - } - } - - /** - * Wertet die Metadaten eines Resultsets fuer eine Tabelle aus, - * um die alle Columns und Typen einer Tabelle zu ermitteln. - */ - private void get_meta_data () throws StorageObjectFailure { - Connection con = null; - PreparedStatement pstmt = null; - String sql = "select * from " + theTable + " where 0=1"; - try { - con = getPooledCon(); - pstmt = con.prepareStatement(sql); - //theLog.printInfo("METADATA: " + sql); - ResultSet rs = pstmt.executeQuery(); - evalMetaData(rs.getMetaData()); - rs.close(); - } catch (SQLException e) { - throwSQLException(e, "get_meta_data"); - } finally { - freeConnection(con, pstmt); - } - } - - - public Connection getPooledCon() throws StorageObjectFailure { - /* @todo , doublecheck but I'm pretty sure that this is unnecessary. -mh - try{ - Class.forName("com.codestudio.sql.PoolMan").newInstance(); - } catch (Exception e){ - throw new StorageObjectException("Could not find the PoolMan Driver" - +e.toString()); - }*/ - Connection con = null; - - try{ - con = SQLManager.getInstance().requestConnection(); - } - catch(SQLException e){ - theLog.printError("could not connect to the database "+e.getMessage()); - System.err.println("could not connect to the database "+e.getMessage()); - throw new StorageObjectFailure("Could not connect to the database",e); - } - - return con; - } - - public void freeConnection (Connection con, Statement stmt) throws StorageObjectFailure { - SQLManager.closeStatement(stmt); - SQLManager.getInstance().returnConnection(con); - } - - /** - * Wertet SQLException aus und wirft dannach eine StorageObjectException - * @param sqe SQLException - * @param wo Funktonsname, in der die SQLException geworfen wurde - * @exception StorageObjectException - */ - protected void throwSQLException (SQLException sqe, String wo) - throws StorageObjectFailure { - String state = ""; - String message = ""; - int vendor = 0; - if (sqe != null) { - state = sqe.getSQLState(); - message = sqe.getMessage(); - vendor = sqe.getErrorCode(); - } - theLog.printError(state + ": " + vendor + " : " + message + " Funktion: " - + wo); - throw new StorageObjectFailure( - (sqe == null) ? "undefined sql exception" :sqe.getMessage(),sqe - ); - } - - protected void _throwStorageObjectException (Exception e, String wo) - throws StorageObjectFailure { - - if (e != null) { - theLog.printError(e.getMessage()+ wo); - throw new StorageObjectFailure(wo, e); - } - else { - theLog.printError(wo); - throw new StorageObjectFailure(wo,null); - } - - } - - /** - * Loggt Fehlermeldung mit dem Parameter Message und wirft dannach - * eine StorageObjectException - * @param message Nachricht mit dem Fehler - * @exception StorageObjectException - */ - void throwStorageObjectException (String message) - throws StorageObjectFailure { - _throwStorageObjectException(null, message); - } - -} - - - +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ +package mir.storage; + +import com.codestudio.util.SQLManager; + +import freemarker.template.SimpleHash; +import freemarker.template.SimpleList; + +import mir.config.MirPropertiesConfiguration; + +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; + +import mir.entity.Entity; +import mir.entity.EntityList; +import mir.entity.StorableObjectEntity; + +import mir.misc.HTMLTemplateProcessor; +import mir.misc.Logfile; +import mir.misc.StringUtil; + +import mir.storage.store.ObjectStore; +import mir.storage.store.StorableObject; +import mir.storage.store.StoreContainerType; +import mir.storage.store.StoreIdentifier; +import mir.storage.store.StoreUtil; + +import mir.util.JDBCStringRoutines; + +import java.io.IOException; +import java.io.InputStreamReader; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; + + +/** + * Diese Klasse implementiert die Zugriffsschicht auf die Datenbank. + * Alle Projektspezifischen Datenbankklassen erben von dieser Klasse. + * In den Unterklassen wird im Minimalfall nur die Tabelle angegeben. + * Im Konfigurationsfile findet sich eine Verweis auf den verwendeten + * Treiber, Host, User und Passwort, ueber den der Zugriff auf die + * Datenbank erfolgt. + * + * @version $Id: Database.java,v 1.32 2003/01/28 21:47:42 idfx Exp $ + * @author rk + * + */ +public class Database implements StorageObject { + private static Class GENERIC_ENTITY_CLASS = null; + private static Class STORABLE_OBJECT_ENTITY_CLASS = null; + private static SimpleHash POPUP_EMTYLINE = new SimpleHash(); + protected static final ObjectStore o_store = ObjectStore.getInstance(); + private static final int _millisPerHour = 60 * 60 * 1000; + private static final int _millisPerMinute = 60 * 1000; + + static { + // always same object saves a little space + POPUP_EMTYLINE.put("key", ""); + POPUP_EMTYLINE.put("value", "--"); + + try { + GENERIC_ENTITY_CLASS = Class.forName("mir.entity.StorableObjectEntity"); + STORABLE_OBJECT_ENTITY_CLASS = + Class.forName("mir.entity.StorableObjectEntity"); + } catch (Exception e) { + System.err.println("FATAL: Database.java could not initialize" + + e.getMessage()); + } + } + + protected MirPropertiesConfiguration configuration; + protected String theTable; + protected String theCoreTable = null; + protected String thePKeyName = "id"; + protected int thePKeyType; + protected int thePKeyIndex; + protected boolean evaluatedMetaData = false; + protected ArrayList metadataFields; + protected ArrayList metadataLabels; + protected ArrayList metadataNotNullFields; + protected int[] metadataTypes; + protected Class theEntityClass; + protected StorageObject myselfDatabase; + protected SimpleList popupCache = null; + protected boolean hasPopupCache = false; + protected SimpleHash hashCache = null; + protected boolean hasTimestamp = true; + private String database_driver; + private String database_url; + private int defaultLimit; + protected DatabaseAdaptor theAdaptor; + protected Logfile theLog; + private SimpleDateFormat _dateFormatterOut = + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private SimpleDateFormat _dateFormatterIn = + new SimpleDateFormat("yyyy-MM-dd HH:mm"); + private Calendar _cal = new GregorianCalendar(); + + /** + * Kontruktor bekommt den Filenamen des Konfigurationsfiles ?bergeben. + * Aus diesem file werden Database.Logfile, + * Database.Username,Database.Password, + * Database.Host und Database.Adaptor + * ausgelesen und ein Broker f?r die Verbindugen zur Datenbank + * erzeugt. + * + * @param String confFilename Dateiname der Konfigurationsdatei + */ + public Database() throws StorageObjectFailure { + try { + configuration = MirPropertiesConfiguration.instance(); + } catch (PropertiesConfigExc e) { + throw new StorageObjectFailure(e); + } + + theLog = + Logfile.getInstance(configuration.getStringWithHome("Database.Logfile")); + + String theAdaptorName = configuration.getString("Database.Adaptor"); + defaultLimit = Integer.parseInt(configuration.getString("Database.Limit")); + + try { + theEntityClass = GENERIC_ENTITY_CLASS; + theAdaptor = + (DatabaseAdaptor) Class.forName(theAdaptorName).newInstance(); + } catch (Exception e) { + theLog.printError("Error in Database() constructor with " + + theAdaptorName + " -- " + e.getMessage()); + throw new StorageObjectFailure("Error in Database() constructor.", e); + } + } + + /** + * Liefert die Entity-Klasse zur?ck, in der eine Datenbankzeile gewrappt + * wird. Wird die Entity-Klasse durch die erbende Klasse nicht ?berschrieben, + * wird eine mir.entity.GenericEntity erzeugt. + * + * @return Class-Objekt der Entity + */ + public java.lang.Class getEntityClass() { + return theEntityClass; + } + + /** + * Liefert die Standardbeschr?nkung von select-Statements zur?ck, also + * wieviel Datens?tze per Default selektiert werden. + * + * @return Standard-Anzahl der Datens?tze + */ + public int getLimit() { + return defaultLimit; + } + + /** + * Liefert den Namen des Primary-Keys zur?ck. Wird die Variable nicht von + * der erbenden Klasse ?berschrieben, so ist der Wert PKEY + * @return Name des Primary-Keys + */ + public String getIdName() { + return thePKeyName; + } + + /** + * Liefert den Namen der Tabelle, auf das sich das Datenbankobjekt bezieht. + * + * @return Name der Tabelle + */ + public String getTableName() { + return theTable; + } + + /* + * Dient dazu vererbte Tabellen bei objectrelationalen DBMS + * zu speichern, wenn die id einer Tabelle in der parenttabelle verwaltet + * wird. + * @return liefert theCoreTabel als String zurueck, wenn gesetzt, sonst + * the Table + */ + public String getCoreTable() { + if (theCoreTable != null) { + return theCoreTable; + } else { + return theTable; + } + } + + /** + * Liefert Feldtypen der Felder der Tabelle zurueck (s.a. java.sql.Types) + * @return int-Array mit den Typen der Felder + * @exception StorageObjectException + */ + public int[] getTypes() throws StorageObjectFailure { + if (metadataTypes == null) { + get_meta_data(); + } + + return metadataTypes; + } + + /** + * Liefert eine Liste der Labels der Tabellenfelder + * @return ArrayListe mit Labeln + * @exception StorageObjectException + */ + public ArrayList getLabels() throws StorageObjectFailure { + if (metadataLabels == null) { + get_meta_data(); + } + + return metadataLabels; + } + + /** + * Liefert eine Liste der Felder der Tabelle + * @return ArrayList mit Feldern + * @exception StorageObjectException + */ + public ArrayList getFields() throws StorageObjectFailure { + if (metadataFields == null) { + get_meta_data(); + } + + return metadataFields; + } + + /* + * Gets value out of ResultSet according to type and converts to String + * @param inValue Wert aus ResultSet. + * @param aType Datenbanktyp. + * @return liefert den Wert als String zurueck. Wenn keine Umwandlung moeglich + * dann /unsupported value/ + */ + private String getValueAsString(ResultSet rs, int valueIndex, int aType) + throws StorageObjectFailure { + String outValue = null; + + if (rs != null) { + try { + switch (aType) { + case java.sql.Types.BIT: + outValue = (rs.getBoolean(valueIndex) == true) ? "1" : "0"; + + break; + + case java.sql.Types.INTEGER: + case java.sql.Types.SMALLINT: + case java.sql.Types.TINYINT: + case java.sql.Types.BIGINT: + + int out = rs.getInt(valueIndex); + + if (!rs.wasNull()) { + outValue = new Integer(out).toString(); + } + + break; + + case java.sql.Types.NUMERIC: + + /** @todo Numeric can be float or double depending upon + * metadata.getScale() / especially with oracle */ + long outl = rs.getLong(valueIndex); + + if (!rs.wasNull()) { + outValue = new Long(outl).toString(); + } + + break; + + case java.sql.Types.REAL: + + float tempf = rs.getFloat(valueIndex); + + if (!rs.wasNull()) { + tempf *= 10; + tempf += 0.5; + + int tempf_int = (int) tempf; + tempf = (float) tempf_int; + tempf /= 10; + outValue = "" + tempf; + outValue = outValue.replace('.', ','); + } + + break; + + case java.sql.Types.DOUBLE: + + double tempd = rs.getDouble(valueIndex); + + if (!rs.wasNull()) { + tempd *= 10; + tempd += 0.5; + + int tempd_int = (int) tempd; + tempd = (double) tempd_int; + tempd /= 10; + outValue = "" + tempd; + outValue = outValue.replace('.', ','); + } + + break; + + case java.sql.Types.CHAR: + case java.sql.Types.VARCHAR: + case java.sql.Types.LONGVARCHAR: + outValue = rs.getString(valueIndex); + + break; + + case java.sql.Types.LONGVARBINARY: + outValue = rs.getString(valueIndex); + + break; + + case java.sql.Types.TIMESTAMP: + + // it's important to use Timestamp here as getting it + // as a string is undefined and is only there for debugging + // according to the API. we can make it a string through formatting. + // -mh + Timestamp timestamp = (rs.getTimestamp(valueIndex)); + + if (!rs.wasNull()) { + java.util.Date date = new java.util.Date(timestamp.getTime()); + outValue = _dateFormatterOut.format(date); + _cal.setTime(date); + + int offset = + _cal.get(Calendar.ZONE_OFFSET) + _cal.get(Calendar.DST_OFFSET); + String tzOffset = + StringUtil.zeroPaddingNumber(offset / _millisPerHour, 2, 2); + outValue = outValue + "+" + tzOffset; + } + + break; + + default: + outValue = ""; + theLog.printWarning("Unsupported Datatype: at " + valueIndex + " (" + + aType + ")"); + } + } catch (SQLException e) { + throw new StorageObjectFailure("Could not get Value out of Resultset -- ", + e); + } + } + + return outValue; + } + + /* + * select-Operator um einen Datensatz zu bekommen. + * @param id Primaerschluessel des Datensatzes. + * @return liefert EntityObject des gefundenen Datensatzes oder null. + */ + public Entity selectById(String id) throws StorageObjectExc { + if ((id == null) || id.equals("")) { + throw new StorageObjectExc("id war null"); + } + + // ask object store for object + if (StoreUtil.implementsStorableObject(theEntityClass)) { + String uniqueId = id; + + if (theEntityClass.equals(StorableObjectEntity.class)) { + uniqueId += ("@" + theTable); + } + + StoreIdentifier search_sid = + new StoreIdentifier(theEntityClass, uniqueId); + theLog.printDebugInfo("CACHE: (dbg) looking for sid " + + search_sid.toString()); + + Entity hit = (Entity) o_store.use(search_sid); + + if (hit != null) { + return hit; + } + } + + Statement stmt = null; + Connection con = getPooledCon(); + Entity returnEntity = null; + + try { + ResultSet rs; + + /** @todo better prepared statement */ + String selectSql = + "select * from " + theTable + " where " + thePKeyName + "=" + id; + stmt = con.createStatement(); + rs = executeSql(stmt, selectSql); + + if (rs != null) { + if (evaluatedMetaData == false) { + evalMetaData(rs.getMetaData()); + } + + if (rs.next()) { + returnEntity = makeEntityFromResultSet(rs); + } else { + theLog.printDebugInfo("Keine daten fuer id: " + id + "in Tabelle" + + theTable); + } + + rs.close(); + } else { + theLog.printDebugInfo("No Data for Id " + id + " in Table " + theTable); + } + } catch (SQLException sqe) { + throwSQLException(sqe, "selectById"); + + return null; + } catch (NumberFormatException e) { + theLog.printError("ID ist keine Zahl: " + id); + } finally { + freeConnection(con, stmt); + } + + /** @todo OS: Entity should be saved in ostore */ + return returnEntity; + } + + /** + * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. + * @param key Datenbankfeld der Bedingung. + * @param value Wert die der key anehmen muss. + * @return EntityList mit den gematchten Entities + */ + public EntityList selectByFieldValue(String aField, String aValue) + throws StorageObjectFailure { + return selectByFieldValue(aField, aValue, 0); + } + + /** + * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. + * @param key Datenbankfeld der Bedingung. + * @param value Wert die der key anehmen muss. + * @param offset Gibt an ab welchem Datensatz angezeigt werden soll. + * @return EntityList mit den gematchten Entities + */ + public EntityList selectByFieldValue(String aField, String aValue, int offset) + throws StorageObjectFailure { + return selectByWhereClause(aField + "=" + aValue, offset); + } + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. + * Also offset wird der erste Datensatz genommen. + * + * @param wc where-Clause + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String where) + throws StorageObjectFailure { + return selectByWhereClause(where, 0); + } + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. + * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. + * + * @param wc where-Clause + * @param offset ab welchem Datensatz. + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String whereClause, int offset) + throws StorageObjectFailure { + return selectByWhereClause(whereClause, null, offset); + } + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. + * Also offset wird der erste Datensatz genommen. + * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. + * + * @param wc where-Clause + * @param ob orderBy-Clause + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String where, String order) + throws StorageObjectFailure { + return selectByWhereClause(where, order, 0); + } + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. + * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. + * + * @param wc where-Clause + * @param ob orderBy-Clause + * @param offset ab welchem Datensatz + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String whereClause, String orderBy, + int offset) throws StorageObjectFailure { + return selectByWhereClause(whereClause, orderBy, offset, defaultLimit); + } + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. + * @param wc where-Clause + * @param ob orderBy-Clause + * @param offset ab welchem Datensatz + * @param limit wieviele Datens?tze + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String wc, String ob, int offset, + int limit) throws StorageObjectFailure { + // check o_store for entitylist + if (StoreUtil.implementsStorableObject(theEntityClass)) { + StoreIdentifier search_sid = + new StoreIdentifier(theEntityClass, + StoreContainerType.STOC_TYPE_ENTITYLIST, + StoreUtil.getEntityListUniqueIdentifierFor(theTable, wc, ob, offset, + limit)); + EntityList hit = (EntityList) o_store.use(search_sid); + + if (hit != null) { + theLog.printDebugInfo("CACHE (hit): " + search_sid.toString()); + + return hit; + } + } + + // local + EntityList theReturnList = null; + Connection con = null; + Statement stmt = null; + ResultSet rs; + int offsetCount = 0; + int count = 0; + + // build sql-statement + + /** @todo count sql string should only be assembled if we really count + * see below at the end of method //rk */ + if ((wc != null) && (wc.length() == 0)) { + wc = null; + } + + StringBuffer countSql = + new StringBuffer("select count(*) from ").append(theTable); + StringBuffer selectSql = + new StringBuffer("select * from ").append(theTable); + + if (wc != null) { + selectSql.append(" where ").append(wc); + countSql.append(" where ").append(wc); + } + + if ((ob != null) && !(ob.length() == 0)) { + selectSql.append(" order by ").append(ob); + } + + if (theAdaptor.hasLimit()) { + if ((limit > -1) && (offset > -1)) { + selectSql.append(" LIMIT ").append(limit).append(" OFFSET ").append(offset); + } + } + + // execute sql + try { + con = getPooledCon(); + stmt = con.createStatement(); + + // selecting... + rs = executeSql(stmt, selectSql.toString()); + + if (rs != null) { + if (!evaluatedMetaData) { + evalMetaData(rs.getMetaData()); + } + + theReturnList = new EntityList(); + + Entity theResultEntity; + + while (rs.next()) { + theResultEntity = makeEntityFromResultSet(rs); + theReturnList.add(theResultEntity); + offsetCount++; + } + + rs.close(); + } + + // making entitylist infos + if (!(theAdaptor.hasLimit())) { + count = offsetCount; + } + + if (theReturnList != null) { + // now we decide if we have to know an overall count... + count = offsetCount; + + if ((limit > -1) && (offset > -1)) { + if (offsetCount == limit) { + /** @todo counting should be deffered to entitylist + * getSize() should be used */ + rs = executeSql(stmt, countSql.toString()); + + if (rs != null) { + if (rs.next()) { + count = rs.getInt(1); + } + + rs.close(); + } else { + theLog.printError("Could not count: " + countSql); + } + } + } + + theReturnList.setCount(count); + theReturnList.setOffset(offset); + theReturnList.setWhere(wc); + theReturnList.setOrder(ob); + theReturnList.setStorage(this); + theReturnList.setLimit(limit); + + if (offset >= limit) { + theReturnList.setPrevBatch(offset - limit); + } + + if ((offset + offsetCount) < count) { + theReturnList.setNextBatch(offset + limit); + } + + if (StoreUtil.implementsStorableObject(theEntityClass)) { + StoreIdentifier sid = theReturnList.getStoreIdentifier(); + theLog.printDebugInfo("CACHE (add): " + sid.toString()); + o_store.add(sid); + } + } + } catch (SQLException sqe) { + throwSQLException(sqe, "selectByWhereClause"); + } finally { + try { + if (con != null) { + freeConnection(con, stmt); + } + } catch (Throwable t) { + } + } + + return theReturnList; + } + + /** + * Bastelt aus einer Zeile der Datenbank ein EntityObjekt. + * + * @param rs Das ResultSetObjekt. + * @return Entity Die Entity. + */ + private Entity makeEntityFromResultSet(ResultSet rs) + throws StorageObjectFailure { + /** @todo OS: get Pkey from ResultSet and consult ObjectStore */ + HashMap theResultHash = new HashMap(); + String theResult = null; + int theType; + Entity returnEntity = null; + + try { + int size = metadataFields.size(); + + for (int i = 0; i < size; i++) { + // alle durchlaufen bis nix mehr da + theType = metadataTypes[i]; + + if (theType == java.sql.Types.LONGVARBINARY) { + InputStreamReader is = + (InputStreamReader) rs.getCharacterStream(i + 1); + + if (is != null) { + char[] data = new char[32768]; + StringBuffer theResultString = new StringBuffer(); + int len; + + while ((len = is.read(data)) > 0) { + theResultString.append(data, 0, len); + } + + is.close(); + theResult = theResultString.toString(); + } else { + theResult = null; + } + } else { + theResult = getValueAsString(rs, (i + 1), theType); + } + + if (theResult != null) { + theResultHash.put(metadataFields.get(i), theResult); + } + } + + if (theEntityClass != null) { + returnEntity = (Entity) theEntityClass.newInstance(); + returnEntity.setValues(theResultHash); + returnEntity.setStorage(myselfDatabase); + + if (returnEntity instanceof StorableObject) { + theLog.printDebugInfo("CACHE: ( in) " + returnEntity.getId() + " :" + + theTable); + o_store.add(((StorableObject) returnEntity).getStoreIdentifier()); + } + } else { + throwStorageObjectException("Internal Error: theEntityClass not set!"); + } + } catch (IllegalAccessException e) { + throwStorageObjectException("No access! -- " + e.getMessage()); + } catch (IOException e) { + throwStorageObjectException("IOException! -- " + e.getMessage()); + } catch (InstantiationException e) { + throwStorageObjectException("No Instatiation! -- " + e.getMessage()); + } catch (SQLException sqe) { + throwSQLException(sqe, "makeEntityFromResultSet"); + + return null; + } + + return returnEntity; + } + + /** + * insert-Operator: f?gt eine Entity in die Tabelle ein. Eine Spalte WEBDB_CREATE + * wird automatisch mit dem aktuellen Datum gefuellt. + * + * @param theEntity + * @return der Wert des Primary-keys der eingef?gten Entity + */ + public String insert(Entity theEntity) throws StorageObjectFailure { + //cache + invalidatePopupCache(); + + // invalidating all EntityLists corresponding with theEntityClass + if (StoreUtil.implementsStorableObject(theEntityClass)) { + StoreContainerType stoc_type = + StoreContainerType.valueOf(theEntityClass, + StoreContainerType.STOC_TYPE_ENTITYLIST); + o_store.invalidate(stoc_type); + } + + String returnId = null; + Connection con = null; + PreparedStatement pstmt = null; + + try { + ArrayList streamedInput = theEntity.streamedInput(); + StringBuffer f = new StringBuffer(); + StringBuffer v = new StringBuffer(); + String aField; + String aValue; + boolean firstField = true; + + // make sql-string + for (int i = 0; i < getFields().size(); i++) { + aField = (String) getFields().get(i); + + if (!aField.equals(thePKeyName)) { + aValue = null; + + // sonderfaelle + if (aField.equals("webdb_create") || + aField.equals("webdb_lastchange")) { + aValue = "NOW()"; + } else { + if ((streamedInput != null) && streamedInput.contains(aField)) { + aValue = "?"; + } else { + if (theEntity.hasValueForField(aField)) { + aValue = + "'" + + JDBCStringRoutines.escapeStringLiteral((String) theEntity.getValue( + aField)) + "'"; + } + } + } + + // wenn Wert gegeben, dann einbauen + if (aValue != null) { + if (firstField == false) { + f.append(","); + v.append(","); + } else { + firstField = false; + } + + f.append(aField); + v.append(aValue); + } + } + } + // end for + + // insert into db + StringBuffer sqlBuf = + new StringBuffer("insert into ").append(theTable).append("(").append(f) + .append(") values (").append(v).append(")"); + String sql = sqlBuf.toString(); + + //theLog.printInfo("INSERT: " + sql); + con = getPooledCon(); + con.setAutoCommit(false); + pstmt = con.prepareStatement(sql); + + if (streamedInput != null) { + for (int i = 0; i < streamedInput.size(); i++) { + String inputString = + (String) theEntity.getValue((String) streamedInput.get(i)); + pstmt.setBytes(i + 1, inputString.getBytes()); + } + } + + int ret = pstmt.executeUpdate(); + + if (ret == 0) { + //insert failed + return null; + } + + pstmt = + con.prepareStatement(theAdaptor.getLastInsertSQL( + (Database) myselfDatabase)); + + ResultSet rs = pstmt.executeQuery(); + rs.next(); + returnId = rs.getString(1); + theEntity.setId(returnId); + } catch (SQLException sqe) { + throwSQLException(sqe, "insert"); + } finally { + try { + con.setAutoCommit(true); + } catch (Exception e) { + ; + } + + freeConnection(con, pstmt); + } + + /** @todo store entity in o_store */ + return returnId; + } + + /** + * update-Operator: aktualisiert eine Entity. Eine Spalte WEBDB_LASTCHANGE + * wird automatisch mit dem aktuellen Datum gefuellt. + * + * @param theEntity + */ + public void update(Entity theEntity) throws StorageObjectFailure { + Connection con = null; + PreparedStatement pstmt = null; + + /** @todo this is stupid: why do we prepare statement, when we + * throw it away afterwards. should be regular statement + * update/insert could better be one routine called save() + * that chooses to either insert or update depending if we + * have a primary key in the entity. i don't know if we + * still need the streamed input fields. // rk */ + /** @todo extension: check if Entity did change, otherwise we don't need + * the roundtrip to the database */ + /** invalidating corresponding entitylists in o_store*/ + if (StoreUtil.implementsStorableObject(theEntityClass)) { + StoreContainerType stoc_type = + StoreContainerType.valueOf(theEntityClass, + StoreContainerType.STOC_TYPE_ENTITYLIST); + o_store.invalidate(stoc_type); + } + + ArrayList streamedInput = theEntity.streamedInput(); + String id = theEntity.getId(); + String aField; + StringBuffer fv = new StringBuffer(); + boolean firstField = true; + + //cache + invalidatePopupCache(); + + // build sql statement + for (int i = 0; i < getFields().size(); i++) { + aField = (String) metadataFields.get(i); + + // only normal cases + if (!(aField.equals(thePKeyName) || aField.equals("webdb_create") || + aField.equals("webdb_lastchange") || + ((streamedInput != null) && streamedInput.contains(aField)))) { + if (theEntity.hasValueForField(aField)) { + if (firstField == false) { + fv.append(", "); + } else { + firstField = false; + } + + fv.append(aField).append("='") + .append(JDBCStringRoutines.escapeStringLiteral( + (String) theEntity.getValue(aField))).append("'"); + + // fv.append(aField).append("='").append(StringUtil.quote((String)theEntity.getValue(aField))).append("'"); + } + } + } + + StringBuffer sql = + new StringBuffer("update ").append(theTable).append(" set ").append(fv); + + // exceptions + if (metadataFields.contains("webdb_lastchange")) { + sql.append(",webdb_lastchange=NOW()"); + } + + // special case: the webdb_create requires the field in yyyy-mm-dd HH:mm + // format so anything extra will be ignored. -mh + if (metadataFields.contains("webdb_create") && + theEntity.hasValueForField("webdb_create")) { + // minimum of 10 (yyyy-mm-dd)... + if (theEntity.getValue("webdb_create").length() >= 10) { + String dateString = theEntity.getValue("webdb_create"); + + // if only 10, then add 00:00 so it doesn't throw a ParseException + if (dateString.length() == 10) { + dateString = dateString + " 00:00"; + } + + // TimeStamp stuff + try { + java.util.Date d = _dateFormatterIn.parse(dateString); + Timestamp tStamp = new Timestamp(d.getTime()); + sql.append(",webdb_create='" + tStamp.toString() + "'"); + } catch (ParseException e) { + throw new StorageObjectFailure(e); + } + } + } + + if (streamedInput != null) { + for (int i = 0; i < streamedInput.size(); i++) { + sql.append(",").append(streamedInput.get(i)).append("=?"); + } + } + + sql.append(" where id=").append(id); + + //theLog.printInfo("UPDATE: " + sql); + // execute sql + try { + con = getPooledCon(); + con.setAutoCommit(false); + pstmt = con.prepareStatement(sql.toString()); + + if (streamedInput != null) { + for (int i = 0; i < streamedInput.size(); i++) { + String inputString = + theEntity.getValue((String) streamedInput.get(i)); + pstmt.setBytes(i + 1, inputString.getBytes()); + } + } + + pstmt.executeUpdate(); + } catch (SQLException sqe) { + throwSQLException(sqe, "update"); + } finally { + try { + con.setAutoCommit(true); + } catch (Exception e) { + ; + } + + freeConnection(con, pstmt); + } + } + + /* + * delete-Operator + * @param id des zu loeschenden Datensatzes + * @return boolean liefert true zurueck, wenn loeschen erfolgreich war. + */ + public boolean delete(String id) throws StorageObjectFailure { + invalidatePopupCache(); + + // ostore send notification + if (StoreUtil.implementsStorableObject(theEntityClass)) { + String uniqueId = id; + + if (theEntityClass.equals(StorableObjectEntity.class)) { + uniqueId += ("@" + theTable); + } + + theLog.printInfo("CACHE: (del) " + id); + + StoreIdentifier search_sid = + new StoreIdentifier(theEntityClass, + StoreContainerType.STOC_TYPE_ENTITY, uniqueId); + o_store.invalidate(search_sid); + } + + /** @todo could be prepared Statement */ + Statement stmt = null; + Connection con = null; + int res = 0; + String sql = + "delete from " + theTable + " where " + thePKeyName + "='" + id + "'"; + + //theLog.printInfo("DELETE " + sql); + try { + con = getPooledCon(); + stmt = con.createStatement(); + res = stmt.executeUpdate(sql); + } catch (SQLException sqe) { + throwSQLException(sqe, "delete"); + } finally { + freeConnection(con, stmt); + } + + return (res > 0) ? true : false; + } + + /* noch nicht implementiert. + * @return immer false + */ + public boolean delete(EntityList theEntityList) { + invalidatePopupCache(); + + return false; + } + + /** + * Diese Methode sollte ueberschrieben werden, wenn fuer die abgeleitete Database-Klasse + * eine SimpleList mit Standard-Popupdaten erzeugt werden koennen soll. + * @return null + */ + public SimpleList getPopupData() throws StorageObjectFailure { + return null; + } + + /** + * Holt Daten fuer Popups. + * @param name Name des Feldes. + * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. + * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + */ + public SimpleList getPopupData(String name, boolean hasNullValue) + throws StorageObjectFailure { + return getPopupData(name, hasNullValue, null); + } + + /** + * Holt Daten fuer Popups. + * @param name Name des Feldes. + * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. + * @param where Schraenkt die Selektion der Datensaetze ein. + * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + */ + public SimpleList getPopupData(String name, boolean hasNullValue, String where) + throws StorageObjectFailure { + return getPopupData(name, hasNullValue, where, null); + } + + /** + * Holt Daten fuer Popups. + * @param name Name des Feldes. + * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. + * @param where Schraenkt die Selektion der Datensaetze ein. + * @param order Gibt ein Feld als Sortierkriterium an. + * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + */ + public SimpleList getPopupData(String name, boolean hasNullValue, + String where, String order) throws StorageObjectFailure { + // caching + if (hasPopupCache && (popupCache != null)) { + return popupCache; + } + + SimpleList simpleList = null; + Connection con = null; + Statement stmt = null; + + // build sql + StringBuffer sql = + new StringBuffer("select ").append(thePKeyName).append(",").append(name) + .append(" from ").append(theTable); + + if ((where != null) && !(where.length() == 0)) { + sql.append(" where ").append(where); + } + + sql.append(" order by "); + + if ((order != null) && !(order.length() == 0)) { + sql.append(order); + } else { + sql.append(name); + } + + // execute sql + try { + con = getPooledCon(); + } catch (Exception e) { + throw new StorageObjectFailure(e); + } + + try { + stmt = con.createStatement(); + + ResultSet rs = executeSql(stmt, sql.toString()); + + if (rs != null) { + if (!evaluatedMetaData) { + get_meta_data(); + } + + simpleList = new SimpleList(); + + // if popup has null-selector + if (hasNullValue) { + simpleList.add(POPUP_EMTYLINE); + } + + SimpleHash popupDict; + + while (rs.next()) { + popupDict = new SimpleHash(); + popupDict.put("key", getValueAsString(rs, 1, thePKeyType)); + popupDict.put("value", rs.getString(2)); + simpleList.add(popupDict); + } + + rs.close(); + } + } catch (Exception e) { + theLog.printError("getPopupData: " + e.getMessage()); + throw new StorageObjectFailure(e); + } finally { + freeConnection(con, stmt); + } + + if (hasPopupCache) { + popupCache = simpleList; + } + + return simpleList; + } + + /** + * Liefert alle Daten der Tabelle als SimpleHash zurueck. Dies wird verwandt, + * wenn in den Templates ein Lookup-Table benoetigt wird. Sollte nur bei kleinen + * Tabellen Verwendung finden. + * @return SimpleHash mit den Tabellezeilen. + */ + public SimpleHash getHashData() { + /** @todo dangerous! this should have a flag to be enabled, otherwise + * very big Hashes could be returned */ + if (hashCache == null) { + try { + hashCache = + HTMLTemplateProcessor.makeSimpleHash(selectByWhereClause("", -1)); + } catch (StorageObjectFailure e) { + theLog.printDebugInfo(e.getMessage()); + } + } + + return hashCache; + } + + /* invalidates the popupCache + */ + protected void invalidatePopupCache() { + /** @todo invalidates toooo much */ + popupCache = null; + hashCache = null; + } + + /** + * Diese Methode fuehrt den Sqlstring sql aus und timed im Logfile. + * @param stmt Statemnt + * @param sql Sql-String + * @return ResultSet + * @exception StorageObjectException + */ + public ResultSet executeSql(Statement stmt, String sql) + throws StorageObjectFailure, SQLException { + long startTime = System.currentTimeMillis(); + ResultSet rs; + + try { + rs = stmt.executeQuery(sql); + + //theLog.printInfo((System.currentTimeMillis() - startTime) + "ms. for: " + sql); + } catch (SQLException e) { + theLog.printDebugInfo("Failed: " + + (System.currentTimeMillis() - startTime) + "ms. for: " + sql); + throw e; + } + + return rs; + } + + /** + * Fuehrt Statement stmt aus und liefert Resultset zurueck. Das SQL-Statment wird + * getimed und geloggt. + * @param stmt PreparedStatement mit der SQL-Anweisung + * @return Liefert ResultSet des Statements zurueck. + * @exception StorageObjectException, SQLException + */ + public ResultSet executeSql(PreparedStatement stmt) + throws StorageObjectFailure, SQLException { + long startTime = (new java.util.Date()).getTime(); + ResultSet rs = stmt.executeQuery(); + theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms."); + + return rs; + } + + /** + * returns the number of rows in the table + */ + public int getSize(String where) throws SQLException, StorageObjectFailure { + long startTime = System.currentTimeMillis(); + String sql = "SELECT Count(*) FROM " + theTable; + + if ((where != null) && !(where.length() == 0)) { + sql = sql + " where " + where; + } + + Connection con = null; + Statement stmt = null; + int result = 0; + + try { + con = getPooledCon(); + stmt = con.createStatement(); + + ResultSet rs = executeSql(stmt, sql); + + while (rs.next()) { + result = rs.getInt(1); + } + } catch (SQLException e) { + theLog.printError(e.getMessage()); + } finally { + freeConnection(con, stmt); + } + + //theLog.printInfo(theTable + " has "+ result +" rows where " + where); + //theLog.printInfo((System.currentTimeMillis() - startTime) + "ms. for: " + sql); + return result; + } + + public int executeUpdate(Statement stmt, String sql) + throws StorageObjectFailure, SQLException { + int rs; + long startTime = (new java.util.Date()).getTime(); + + try { + rs = stmt.executeUpdate(sql); + + //theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); + } catch (SQLException e) { + theLog.printDebugInfo("Failed: " + + (new java.util.Date().getTime() - startTime) + "ms. for: " + sql); + throw e; + } + + return rs; + } + + public int executeUpdate(String sql) + throws StorageObjectFailure, SQLException { + int result = -1; + long startTime = (new java.util.Date()).getTime(); + Connection con = null; + PreparedStatement pstmt = null; + + try { + con = getPooledCon(); + pstmt = con.prepareStatement(sql); + result = pstmt.executeUpdate(); + } catch (Exception e) { + theLog.printDebugInfo("executeUpdate failed: " + e.getMessage()); + throw new StorageObjectFailure("executeUpdate failed", e); + } finally { + freeConnection(con, pstmt); + } + + //theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); + return result; + } + + /** + * Wertet ResultSetMetaData aus und setzt interne Daten entsprechend + * @param md ResultSetMetaData + * @exception StorageObjectException + */ + private void evalMetaData(ResultSetMetaData md) throws StorageObjectFailure { + this.evaluatedMetaData = true; + this.metadataFields = new ArrayList(); + this.metadataLabels = new ArrayList(); + this.metadataNotNullFields = new ArrayList(); + + try { + int numFields = md.getColumnCount(); + this.metadataTypes = new int[numFields]; + + String aField; + int aType; + + for (int i = 1; i <= numFields; i++) { + aField = md.getColumnName(i); + metadataFields.add(aField); + metadataLabels.add(md.getColumnLabel(i)); + aType = md.getColumnType(i); + metadataTypes[i - 1] = aType; + + if (aField.equals(thePKeyName)) { + thePKeyType = aType; + thePKeyIndex = i; + } + + if (md.isNullable(i) == ResultSetMetaData.columnNullable) { + metadataNotNullFields.add(aField); + } + } + } catch (SQLException e) { + throwSQLException(e, "evalMetaData"); + } + } + + /** + * Wertet die Metadaten eines Resultsets fuer eine Tabelle aus, + * um die alle Columns und Typen einer Tabelle zu ermitteln. + */ + private void get_meta_data() throws StorageObjectFailure { + Connection con = null; + PreparedStatement pstmt = null; + String sql = "select * from " + theTable + " where 0=1"; + + try { + con = getPooledCon(); + pstmt = con.prepareStatement(sql); + + //theLog.printInfo("METADATA: " + sql); + ResultSet rs = pstmt.executeQuery(); + evalMetaData(rs.getMetaData()); + rs.close(); + } catch (SQLException e) { + throwSQLException(e, "get_meta_data"); + } finally { + freeConnection(con, pstmt); + } + } + + public Connection getPooledCon() throws StorageObjectFailure { + /* @todo , doublecheck but I'm pretty sure that this is unnecessary. -mh + try{ + Class.forName("com.codestudio.sql.PoolMan").newInstance(); + } catch (Exception e){ + throw new StorageObjectException("Could not find the PoolMan Driver" + +e.toString()); + }*/ + Connection con = null; + + try { + con = SQLManager.getInstance().requestConnection(); + } catch (SQLException e) { + theLog.printError("could not connect to the database " + e.getMessage()); + System.err.println("could not connect to the database " + e.getMessage()); + throw new StorageObjectFailure("Could not connect to the database", e); + } + + return con; + } + + public void freeConnection(Connection con, Statement stmt) + throws StorageObjectFailure { + SQLManager.closeStatement(stmt); + SQLManager.getInstance().returnConnection(con); + } + + /** + * Wertet SQLException aus und wirft dannach eine StorageObjectException + * @param sqe SQLException + * @param wo Funktonsname, in der die SQLException geworfen wurde + * @exception StorageObjectException + */ + protected void throwSQLException(SQLException sqe, String wo) + throws StorageObjectFailure { + String state = ""; + String message = ""; + int vendor = 0; + + if (sqe != null) { + state = sqe.getSQLState(); + message = sqe.getMessage(); + vendor = sqe.getErrorCode(); + } + + theLog.printError(state + ": " + vendor + " : " + message + " Funktion: " + + wo); + throw new StorageObjectFailure((sqe == null) ? "undefined sql exception" + : sqe.getMessage(), sqe); + } + + protected void _throwStorageObjectException(Exception e, String wo) + throws StorageObjectFailure { + if (e != null) { + theLog.printError(e.getMessage() + wo); + throw new StorageObjectFailure(wo, e); + } else { + theLog.printError(wo); + throw new StorageObjectFailure(wo, null); + } + } + + /** + * Loggt Fehlermeldung mit dem Parameter Message und wirft dannach + * eine StorageObjectException + * @param message Nachricht mit dem Fehler + * @exception StorageObjectException + */ + void throwStorageObjectException(String message) throws StorageObjectFailure { + _throwStorageObjectException(null, message); + } +} diff --git a/source/mir/storage/DatabaseAdaptor.java b/source/mir/storage/DatabaseAdaptor.java index cc8e4e9b..c70030fb 100755 --- a/source/mir/storage/DatabaseAdaptor.java +++ b/source/mir/storage/DatabaseAdaptor.java @@ -1,100 +1,96 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ - -package mir.storage; - -import java.util.Properties; - -import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; - - -/** - * Interfacedefinition f?r Datenbank-Adpatoren. Die Adaptoren legen - * jeweils das Verhalten und die Befehlsm?chtigkeit der Datenbank - * fest. - * - * @author - * - * @version $Id: DatabaseAdaptor.java,v 1.4 2003/01/25 17:45:19 idfx Exp $ - */ - -public interface DatabaseAdaptor{ - - /* Liefert den Namen der Adaptorklasse - * @return Adaptorklasse als String - */ - public abstract String getDriver() throws PropertiesConfigExc; - - /** - * Liefert die URL f?r JDBC zur?ck, in den die Parameter user, pass und host - * eingef?gt werden. Die URL wird aus der Konfiguration geholt. - * - * @param user user als String - * @param pass passwort als String - * @param host host als String - * @return url als String - */ - public abstract String getURL(String user, String pass, String host) - throws PropertiesConfigExc; - - /** - * Gibt zur?ck, ob das SQL der Datenbank den limit-Befehl beherrscht. - * @return true wenn ja, sonst false - */ - public abstract boolean hasLimit(); - - /** - * Liefert zur?ck, ob der limit-Befehl erst start und dann offset - * hat (true), oder umgekehrt. Nur Relevant, wenn hasLimit true zur?ckliefert. - * - * @return true wenn erstes, sonst false - */ - public abstract boolean reverseLimit(); - - /** - * Liefert ein Properties-Objekt zurueck mit user und password. - * @param user - * @param password - * @return Properties - */ - public abstract Properties getProperties(String user, String password); - - /** - * Gibt SQL-Stringfragment zur?ck, mit dem nach einem insert-Befehl ermittelt - * werden kann, wie man den primary-Key des eingef?gten Datensatzes bekommt. - * - * @param theDB Database-Objekt, aus dem ggf. noetige Informationen geholt - * werden k?nnen, wie z.B. der Tabellenname - * @return SQL-Statement als String - */ - public abstract String getLastInsertSQL(Database theDB); -} - +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ +package mir.storage; + +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; + +import java.util.Properties; + + +/** + * Interfacedefinition f?r Datenbank-Adpatoren. Die Adaptoren legen + * jeweils das Verhalten und die Befehlsm?chtigkeit der Datenbank + * fest. + * + * @author + * + * @version $Id: DatabaseAdaptor.java,v 1.5 2003/01/28 21:48:30 idfx Exp $ + */ +public interface DatabaseAdaptor { + /* Liefert den Namen der Adaptorklasse + * @return Adaptorklasse als String + */ + public abstract String getDriver() throws PropertiesConfigExc; + + /** + * Liefert die URL f?r JDBC zur?ck, in den die Parameter user, pass und host + * eingef?gt werden. Die URL wird aus der Konfiguration geholt. + * + * @param user user als String + * @param pass passwort als String + * @param host host als String + * @return url als String + */ + public abstract String getURL(String user, String pass, String host) + throws PropertiesConfigExc; + + /** + * Gibt zur?ck, ob das SQL der Datenbank den limit-Befehl beherrscht. + * @return true wenn ja, sonst false + */ + public abstract boolean hasLimit(); + + /** + * Liefert zur?ck, ob der limit-Befehl erst start und dann offset + * hat (true), oder umgekehrt. Nur Relevant, wenn hasLimit true zur?ckliefert. + * + * @return true wenn erstes, sonst false + */ + public abstract boolean reverseLimit(); + + /** + * Liefert ein Properties-Objekt zurueck mit user und password. + * @param user + * @param password + * @return Properties + */ + public abstract Properties getProperties(String user, String password); + + /** + * Gibt SQL-Stringfragment zur?ck, mit dem nach einem insert-Befehl ermittelt + * werden kann, wie man den primary-Key des eingef?gten Datensatzes bekommt. + * + * @param theDB Database-Objekt, aus dem ggf. noetige Informationen geholt + * werden k?nnen, wie z.B. der Tabellenname + * @return SQL-Statement als String + */ + public abstract String getLastInsertSQL(Database theDB); +} diff --git a/source/mir/storage/DatabaseAdaptorMySQL.java b/source/mir/storage/DatabaseAdaptorMySQL.java index cd2d17b9..1e6c9038 100755 --- a/source/mir/storage/DatabaseAdaptorMySQL.java +++ b/source/mir/storage/DatabaseAdaptorMySQL.java @@ -1,73 +1,71 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ - -package mir.storage; - -import java.util.Properties; - -import mir.config.MirPropertiesConfiguration; -import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; - -/** - * Diese Klasse implementiert die abstrakte Klasse DatabaseAdaptor - * - * @author - * @version 27.6.1999 - */ - -public final class DatabaseAdaptorMySQL implements DatabaseAdaptor{ - - public String getDriver() throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.MySQL.Driver"); - } - - public String getURL(String user, String pass, String host) throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.MySQL.URL"); - } - - public boolean hasLimit() { - return true; - } - - public boolean reverseLimit() { - return false; - } - - public Properties getProperties(String user, String password) { - return null; - } - - public String getLastInsertSQL(Database theDB) { - return "select last_insert_id()"; - } -} - - +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ +package mir.storage; + +import mir.config.MirPropertiesConfiguration; + +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; + +import java.util.Properties; + + +/** + * Diese Klasse implementiert die abstrakte Klasse DatabaseAdaptor + * + * @author + * @version 27.6.1999 + */ +public final class DatabaseAdaptorMySQL implements DatabaseAdaptor { + public String getDriver() throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.MySQL.Driver"); + } + + public String getURL(String user, String pass, String host) + throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.MySQL.URL"); + } + + public boolean hasLimit() { + return true; + } + + public boolean reverseLimit() { + return false; + } + + public Properties getProperties(String user, String password) { + return null; + } + + public String getLastInsertSQL(Database theDB) { + return "select last_insert_id()"; + } +} diff --git a/source/mir/storage/DatabaseAdaptorOracle.java b/source/mir/storage/DatabaseAdaptorOracle.java index d2ef2080..e18a98a6 100755 --- a/source/mir/storage/DatabaseAdaptorOracle.java +++ b/source/mir/storage/DatabaseAdaptorOracle.java @@ -31,16 +31,14 @@ /* * put your module comment here */ +package mir.storage; +import mir.config.MirPropertiesConfiguration; - -package mir.storage; +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; import java.util.Properties; -import mir.config.MirPropertiesConfiguration; -import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; - /** * Diese Klasse implementiert Interface DatabaseAdaptor fuer Oracle @@ -48,69 +46,61 @@ import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; * @author * @version 15.05.2000 */ -public final class DatabaseAdaptorOracle - implements DatabaseAdaptor { - - /** - * Liefert den Namen der Adaptorklasse Adaptor.Oracle.Driver - * f?r Oracle zur?ck. - * @return Adaptorklasse als String - */ - public String getDriver() throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.Oracle.Driver"); - } - - /** - * Liefert die URL f?r JDBC zur?ck, in den die Parameter user, pass und host - * eingef?gt werden. Die URL wird aus der Konfiguration geholt. - * - * @param user user als String - * @param pass passwort als String - * @param host host als String - * @return url als String - */ - public String getURL(String user, String pass, String host) throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.Oracle.URL"); - /** @todo hier muesste bessererweise $HOST durch HOST ersetzt, etc. werden */ - - } - - /** - * Gibt zur?ck, ob das SQL der Datenbank den limit-Befehl beherrscht. - * @return false - */ - public boolean hasLimit() { - return false; - } - - /** - * Liefert zur?ck, ob der limit-Befehl erst start und dann offset - * hat (true), oder umgekehrt. Nur Relevant, wenn hasLimit true zur?ckliefert. - * - * @return false - */ - public boolean reverseLimit() { - return false; - } - - /** - * Liefert ein Properties-Objekt zurueck mit user und password. - * @param user - * @param password - * @return Properties - */ - public Properties getProperties(String user, String password) { - return null; - } - - - - - - - - - public String getLastInsertSQL(Database theDB) { - return "select currval('"+theDB.getCoreTable()+"_id_seq')"; - } +public final class DatabaseAdaptorOracle implements DatabaseAdaptor { + /** + * Liefert den Namen der Adaptorklasse Adaptor.Oracle.Driver + * f?r Oracle zur?ck. + * @return Adaptorklasse als String + */ + public String getDriver() throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.Oracle.Driver"); + } + + /** + * Liefert die URL f?r JDBC zur?ck, in den die Parameter user, pass und host + * eingef?gt werden. Die URL wird aus der Konfiguration geholt. + * + * @param user user als String + * @param pass passwort als String + * @param host host als String + * @return url als String + */ + public String getURL(String user, String pass, String host) + throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.Oracle.URL"); + + /** @todo hier muesste bessererweise $HOST durch HOST ersetzt, etc. werden */ + } + + /** + * Gibt zur?ck, ob das SQL der Datenbank den limit-Befehl beherrscht. + * @return false + */ + public boolean hasLimit() { + return false; + } + + /** + * Liefert zur?ck, ob der limit-Befehl erst start und dann offset + * hat (true), oder umgekehrt. Nur Relevant, wenn hasLimit true zur?ckliefert. + * + * @return false + */ + public boolean reverseLimit() { + return false; + } + + /** + * Liefert ein Properties-Objekt zurueck mit user und password. + * @param user + * @param password + * @return Properties + */ + public Properties getProperties(String user, String password) { + return null; + } + + public String getLastInsertSQL(Database theDB) { + return "select currval('" + theDB.getCoreTable() + "_id_seq')"; + } } diff --git a/source/mir/storage/DatabaseAdaptorPostgresql.java b/source/mir/storage/DatabaseAdaptorPostgresql.java index c6de6926..841ff6f4 100755 --- a/source/mir/storage/DatabaseAdaptorPostgresql.java +++ b/source/mir/storage/DatabaseAdaptorPostgresql.java @@ -1,73 +1,71 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ - -package mir.storage; - -import java.util.Properties; - -import mir.config.MirPropertiesConfiguration; -import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; - -/** - * Diese Klasse implementiert die abstrakte Klasse DatabaseAdaptor f?r Postgresql-Datenbanken - * - * @author - * @version 30.12.2000 - */ - -public final class DatabaseAdaptorPostgresql implements DatabaseAdaptor{ - - public String getDriver() throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.PostgreSQL.Driver"); - } - - public String getURL(String user, String pass, String host) throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.PostgreSQL.URL"); - } - - public boolean hasLimit() { - return true; - } - - public boolean reverseLimit() { - return true; - } - - public Properties getProperties(String user, String password) { - return null; - } - - public String getLastInsertSQL(Database theDB) { - return "select currval('" + theDB.getCoreTable() + "_id_seq')"; - } -} - - +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ +package mir.storage; + +import mir.config.MirPropertiesConfiguration; + +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; + +import java.util.Properties; + + +/** + * Diese Klasse implementiert die abstrakte Klasse DatabaseAdaptor f?r Postgresql-Datenbanken + * + * @author + * @version 30.12.2000 + */ +public final class DatabaseAdaptorPostgresql implements DatabaseAdaptor { + public String getDriver() throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.PostgreSQL.Driver"); + } + + public String getURL(String user, String pass, String host) + throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.PostgreSQL.URL"); + } + + public boolean hasLimit() { + return true; + } + + public boolean reverseLimit() { + return true; + } + + public Properties getProperties(String user, String password) { + return null; + } + + public String getLastInsertSQL(Database theDB) { + return "select currval('" + theDB.getCoreTable() + "_id_seq')"; + } +} diff --git a/source/mir/storage/DatabaseAdaptorSybase.java b/source/mir/storage/DatabaseAdaptorSybase.java index b5cd2038..a55a1e38 100755 --- a/source/mir/storage/DatabaseAdaptorSybase.java +++ b/source/mir/storage/DatabaseAdaptorSybase.java @@ -1,110 +1,110 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ -/* - * Implementiert DatabaseAdaptor Interface f?r Sybase. - */ - - - -package mir.storage; - -import java.util.Properties; - -import mir.config.MirPropertiesConfiguration; -import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; - - -/** - * Diese Klasse implementiert Interface DatabaseAdaptor fuer Sybase - * - * @author - * @version 15.05.2000 - */ -public final class DatabaseAdaptorSybase implements DatabaseAdaptor { - - /** - * Liefert den Namen der Adaptorklasse Adaptor.Sybase.Driver - * f?r Sybase zur?ck. - * @return Adaptorklasse als String - */ - public String getDriver() throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.Sybase.Driver"); - } - - /** - * Liefert die URL f?r JDBC zur?ck, in den die Parameter user, pass und host - * eingef?gt werden. Die URL wird aus der Konfiguration geholt. - * - * @param user user als String - * @param pass passwort als String - * @param host host als String - * @return url als String - */ - public String getURL(String user, String pass, String host) throws PropertiesConfigExc { - return MirPropertiesConfiguration.instance().getString("Adaptor.Sybase.URL"); - /** @todo hier muesste bessererweise $HOST durch HOST ersetzt, etc. werden */ - } - - /** - * Gibt zur?ck, ob das SQL der Datenbank den limit-Befehl beherrscht. - * @return false - */ - public boolean hasLimit() { - return false; - } - - /** - * Liefert zur?ck, ob der limit-Befehl erst start und dann offset - * hat (true), oder umgekehrt. Nur Relevant, wenn hasLimit true zur?ckliefert. - * - * @return false - */ - public boolean reverseLimit() { - return false; - } - - /** - * Liefert ein Properties-Objekt zurueck mit user und password. - * @param user - * @param password - * @return Properties - */ - public Properties getProperties(String user, String password) { - Properties props = new Properties(); - props.put("user", user); - props.put("password", password); - return props; - } - - public String getLastInsertSQL(Database theDB) { - return "select currval('" + theDB.getCoreTable() + "_id_seq')"; - } -} +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ +/* + * Implementiert DatabaseAdaptor Interface f?r Sybase. + */ +package mir.storage; + +import mir.config.MirPropertiesConfiguration; + +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; + +import java.util.Properties; + + +/** + * Diese Klasse implementiert Interface DatabaseAdaptor fuer Sybase + * + * @author + * @version 15.05.2000 + */ +public final class DatabaseAdaptorSybase implements DatabaseAdaptor { + /** + * Liefert den Namen der Adaptorklasse Adaptor.Sybase.Driver + * f?r Sybase zur?ck. + * @return Adaptorklasse als String + */ + public String getDriver() throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.Sybase.Driver"); + } + + /** + * Liefert die URL f?r JDBC zur?ck, in den die Parameter user, pass und host + * eingef?gt werden. Die URL wird aus der Konfiguration geholt. + * + * @param user user als String + * @param pass passwort als String + * @param host host als String + * @return url als String + */ + public String getURL(String user, String pass, String host) + throws PropertiesConfigExc { + return MirPropertiesConfiguration.instance().getString("Adaptor.Sybase.URL"); + + /** @todo hier muesste bessererweise $HOST durch HOST ersetzt, etc. werden */ + } + + /** + * Gibt zur?ck, ob das SQL der Datenbank den limit-Befehl beherrscht. + * @return false + */ + public boolean hasLimit() { + return false; + } + + /** + * Liefert zur?ck, ob der limit-Befehl erst start und dann offset + * hat (true), oder umgekehrt. Nur Relevant, wenn hasLimit true zur?ckliefert. + * + * @return false + */ + public boolean reverseLimit() { + return false; + } + + /** + * Liefert ein Properties-Objekt zurueck mit user und password. + * @param user + * @param password + * @return Properties + */ + public Properties getProperties(String user, String password) { + Properties props = new Properties(); + props.put("user", user); + props.put("password", password); + + return props; + } + + public String getLastInsertSQL(Database theDB) { + return "select currval('" + theDB.getCoreTable() + "_id_seq')"; + } +} diff --git a/source/mir/storage/DatabaseCache.java b/source/mir/storage/DatabaseCache.java index 5740525f..dfe9cccd 100755 --- a/source/mir/storage/DatabaseCache.java +++ b/source/mir/storage/DatabaseCache.java @@ -28,126 +28,136 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ - package mir.storage; import java.util.ArrayList; + public class DatabaseCache { private final ArrayList _cache; private int _counter; private final int _max; - - public DatabaseCache(int i_max){ + + public DatabaseCache(int i_max) { _counter = 0; _max = i_max; _cache = new ArrayList(_max); } - - public DatabaseCache(){ + + public DatabaseCache() { _counter = -1; _max = 100; _cache = new ArrayList(_max); } - - public synchronized void put(String key, Object value){ - if(_counter >=_max){ + + public synchronized void put(String key, Object value) { + if (_counter >= _max) { _cache.remove(0); _cache.trimToSize(); - _counter --; + _counter--; System.out.println("put: remove " + _counter); } - _cache.add(new Entry(key,value)); - _counter ++; + + _cache.add(new Entry(key, value)); + _counter++; System.out.println("put: put " + _counter); } - - public synchronized void clear(){ + + public synchronized void clear() { _cache.clear(); } - - public int containsKey(String key){ - for(int i = 0; i<_cache.size(); i++){ - if( _cache.get(i)!=null && ((Entry)_cache.get(i)).getKey().equals(key) ) + + public int containsKey(String key) { + for (int i = 0; i < _cache.size(); i++) { + if ((_cache.get(i) != null) && + ((Entry) _cache.get(i)).getKey().equals(key)) { return i; + } } + return -1; } - - public int containsValue(Object o){ - for(int i = 0; i<_cache.size(); i++){ - if( _cache.get(i)!=null && ((Entry)_cache.get(i)).getValue().equals(o) ) + + public int containsValue(Object o) { + for (int i = 0; i < _cache.size(); i++) { + if ((_cache.get(i) != null) && + ((Entry) _cache.get(i)).getValue().equals(o)) { return i; + } } + return -1; } - - public Object get(String key){ - for(int i = 0; i<_cache.size(); i++){ - if( _cache.get(i) != null && - ((Entry)_cache.get(i)).getKey(key) != null && - ((Entry)_cache.get(i)).getKey(key).equals(key) ) { - System.out.println("test2: "+((Entry)_cache.get(i)).getKey(key)); - return ((Entry)_cache.get(i)).getValue(); + + public Object get(String key) { + for (int i = 0; i < _cache.size(); i++) { + if ((_cache.get(i) != null) && + (((Entry) _cache.get(i)).getKey(key) != null) && + ((Entry) _cache.get(i)).getKey(key).equals(key)) { + System.out.println("test2: " + ((Entry) _cache.get(i)).getKey(key)); + + return ((Entry) _cache.get(i)).getValue(); } } + return null; } - - public synchronized boolean remove(String key){ + + public synchronized boolean remove(String key) { int i = containsKey(key); - if(i==-1){ + + if (i == -1) { return false; } + _cache.remove(i); _cache.trimToSize(); - _counter --; + _counter--; + return true; } - - public int size(){ + + public int size() { return _counter; } - + private class Entry { private String _key; private Object _value; - - public Entry(String i_key, Object i_value){ + + public Entry(String i_key, Object i_value) { _key = i_key; _value = i_value; } - - public void put(String i_key, Object i_value){ + + public void put(String i_key, Object i_value) { _key = i_key; _value = i_value; } - - public Object getValue(String i_key){ - if(i_key.equals(_key)){ + + public Object getValue(String i_key) { + if (i_key.equals(_key)) { return _value; } else { return null; } } - - public Object getValue(){ + + public Object getValue() { return _value; } - - public String getKey(Object i_o){ - if(i_o.equals(_value)){ + + public String getKey(Object i_o) { + if (i_o.equals(_value)) { return _key; } else { return null; } } - public String getKey(){ - return _key; + public String getKey() { + return _key; } - }//Entry - + } + //Entry } - - diff --git a/source/mir/storage/StorageObject.java b/source/mir/storage/StorageObject.java index b39b28bd..773aaedc 100755 --- a/source/mir/storage/StorageObject.java +++ b/source/mir/storage/StorageObject.java @@ -1,235 +1,227 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ -/* - * Implementiert Interface f?r die Speicherschicht. - * Bislang gibt es in der Bibliothek nur die M?glichkeit - * in einer Datenbank zu speichern. - */ - -package mir.storage; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; - -import mir.entity.Entity; -import mir.entity.EntityList; -import freemarker.template.SimpleHash; -import freemarker.template.SimpleList; - - -/** - * Implementiert Interface f?r die Speicherschicht. - * Bislang gibt es in der Bibliothek nur die M?glichkeit - * in einer Datenbank zu speichern. - * @author RK - * @version 29.6.1999 - */ -public interface StorageObject { - - /** - * Dokumentation siehe Database.java - * @param id - * @return Entity - * @exception StorageObjectException - */ - abstract public Entity selectById(String id) throws StorageObjectExc; - - /** - * Dokumentation siehe Database.java - * @param aField - * @param aValue - * @return EntityList - * @exception StorageObjectException - */ - abstract public EntityList selectByFieldValue(String aField, String aValue) throws - StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param whereClause - * @return EntityList - * @exception StorageObjectException - */ - abstract public EntityList selectByWhereClause(String whereClause) throws - StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param whereClause - * @param offset - * @return EntityList - * @exception StorageObjectException - */ - abstract public EntityList selectByWhereClause(String whereClause, int offset) throws - StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param whereClause - * @param orderBy - * @param offset - * @return EntityList - * @exception StorageObjectException - */ - abstract public EntityList selectByWhereClause(String whereClause, - String orderBy, - int offset) throws - StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param whereClause - * @param orderBy - * @param offset - * @param limit - * @return EntityList - * @exception StorageObjectException - */ - abstract public EntityList selectByWhereClause(String whereClause, - String orderBy, - int offset, int limit) throws - StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param id - * @return boolen - * @exception StorageObjectException - */ - abstract public boolean delete(String id) throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @return ArrayList - * @exception StorageObjectException - */ - abstract public ArrayList getFields() throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @return int[] - * @exception StorageObjectException - */ - abstract public int[] getTypes() throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @return ArrayList - * @exception StorageObjectException - */ - abstract public ArrayList getLabels() throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param a - * @exception StorageObjectException - */ - abstract public void update(Entity a) throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param a - * @return String id - * @exception StorageObjectException - */ - abstract public String insert(Entity a) throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @return Class Klasse der Entity - */ - abstract public Class getEntityClass(); - - /** - * put your documentation comment here - * @return - */ - abstract public String getIdName(); - - /** - * Dokumentation siehe Database.java - * @return String - */ - abstract public String getTableName(); - - /** - * Dokumentation siehe Database.java - * @return SimpleHash - */ - abstract public SimpleHash getHashData(); - - /** - * Dokumentation siehe Database.java - * @return Connection - * @exception StorageObjectException - */ - abstract public Connection getPooledCon() throws StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @param a - * @param sql - * @return ResultSet - * @exception StorageObjectException, SQLException - */ - abstract public ResultSet executeSql(Statement a, String sql) throws - StorageObjectFailure, - SQLException; - - /** - * Dokumentation siehe Database.java - * @param con - * @param stmt - */ - abstract public void freeConnection(Connection con, Statement stmt) throws - StorageObjectFailure; - - /** - * Dokumentation siehe Database.java - * @return - */ - abstract public SimpleList getPopupData() throws StorageObjectFailure; - - abstract public int executeUpdate(Statement a, String sql) throws - StorageObjectFailure, SQLException; - - abstract public int executeUpdate(String sql) throws StorageObjectFailure, - SQLException; - - abstract public int getSize(String where) throws SQLException, - StorageObjectFailure; -} - - - +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ +/* + * Implementiert Interface f?r die Speicherschicht. + * Bislang gibt es in der Bibliothek nur die M?glichkeit + * in einer Datenbank zu speichern. + */ +package mir.storage; + +import freemarker.template.SimpleHash; +import freemarker.template.SimpleList; + +import mir.entity.Entity; +import mir.entity.EntityList; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import java.util.ArrayList; + + +/** + * Implementiert Interface f?r die Speicherschicht. + * Bislang gibt es in der Bibliothek nur die M?glichkeit + * in einer Datenbank zu speichern. + * @author RK + * @version 29.6.1999 + */ +public interface StorageObject { + /** + * Dokumentation siehe Database.java + * @param id + * @return Entity + * @exception StorageObjectException + */ + abstract public Entity selectById(String id) throws StorageObjectExc; + + /** + * Dokumentation siehe Database.java + * @param aField + * @param aValue + * @return EntityList + * @exception StorageObjectException + */ + abstract public EntityList selectByFieldValue(String aField, String aValue) + throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param whereClause + * @return EntityList + * @exception StorageObjectException + */ + abstract public EntityList selectByWhereClause(String whereClause) + throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param whereClause + * @param offset + * @return EntityList + * @exception StorageObjectException + */ + abstract public EntityList selectByWhereClause(String whereClause, int offset) + throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param whereClause + * @param orderBy + * @param offset + * @return EntityList + * @exception StorageObjectException + */ + abstract public EntityList selectByWhereClause(String whereClause, + String orderBy, int offset) throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param whereClause + * @param orderBy + * @param offset + * @param limit + * @return EntityList + * @exception StorageObjectException + */ + abstract public EntityList selectByWhereClause(String whereClause, + String orderBy, int offset, int limit) throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param id + * @return boolen + * @exception StorageObjectException + */ + abstract public boolean delete(String id) throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @return ArrayList + * @exception StorageObjectException + */ + abstract public ArrayList getFields() throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @return int[] + * @exception StorageObjectException + */ + abstract public int[] getTypes() throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @return ArrayList + * @exception StorageObjectException + */ + abstract public ArrayList getLabels() throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param a + * @exception StorageObjectException + */ + abstract public void update(Entity a) throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param a + * @return String id + * @exception StorageObjectException + */ + abstract public String insert(Entity a) throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @return Class Klasse der Entity + */ + abstract public Class getEntityClass(); + + /** + * put your documentation comment here + * @return + */ + abstract public String getIdName(); + + /** + * Dokumentation siehe Database.java + * @return String + */ + abstract public String getTableName(); + + /** + * Dokumentation siehe Database.java + * @return SimpleHash + */ + abstract public SimpleHash getHashData(); + + /** + * Dokumentation siehe Database.java + * @return Connection + * @exception StorageObjectException + */ + abstract public Connection getPooledCon() throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @param a + * @param sql + * @return ResultSet + * @exception StorageObjectException, SQLException + */ + abstract public ResultSet executeSql(Statement a, String sql) + throws StorageObjectFailure, SQLException; + + /** + * Dokumentation siehe Database.java + * @param con + * @param stmt + */ + abstract public void freeConnection(Connection con, Statement stmt) + throws StorageObjectFailure; + + /** + * Dokumentation siehe Database.java + * @return + */ + abstract public SimpleList getPopupData() throws StorageObjectFailure; + + abstract public int executeUpdate(Statement a, String sql) + throws StorageObjectFailure, SQLException; + + abstract public int executeUpdate(String sql) + throws StorageObjectFailure, SQLException; + + abstract public int getSize(String where) + throws SQLException, StorageObjectFailure; +} diff --git a/source/mir/storage/StorageObjectExc.java b/source/mir/storage/StorageObjectExc.java index 34a2ec9f..5cb3acdb 100755 --- a/source/mir/storage/StorageObjectExc.java +++ b/source/mir/storage/StorageObjectExc.java @@ -1,17 +1,47 @@ +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ package mir.storage; import multex.Exc; + /** * @author idefix */ public class StorageObjectExc extends Exc { - public StorageObjectExc(){ + public StorageObjectExc() { super("Something gone wrong"); } - public StorageObjectExc(String msg){ + public StorageObjectExc(String msg) { super(msg); } - } diff --git a/source/mir/storage/StorageObjectException.java b/source/mir/storage/StorageObjectException.java deleted file mode 100755 index b90f3fb3..00000000 --- a/source/mir/storage/StorageObjectException.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. - */ -/** - * Exception fuer StorageObject

- * - * @author RK - * @version 30.6.1999 - * - * - */ - - - -package mir.storage; - -import java.lang.*; - - -/** - * Expception Objekt fuer alle Fehler, die in der Speicherzugriffsschicht - * (mir.storage) auftauchen - */ -public class StorageObjectException extends Exception { - - /** - * Leerer Konstruktor - */ - public StorageObjectException () { - super(); - } - - /** - * Konstruktor mit Nachricht - * @param String msg - */ - public StorageObjectException (String msg) { - super(msg); - } -} - - - - diff --git a/source/mir/storage/StorageObjectFailure.java b/source/mir/storage/StorageObjectFailure.java index e87bd5fb..b6cd10f6 100755 --- a/source/mir/storage/StorageObjectFailure.java +++ b/source/mir/storage/StorageObjectFailure.java @@ -28,26 +28,14 @@ * to your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ -/** - * Exception fuer StorageObject

- * - * @author RK - * @version 30.6.1999 - * - * - */ - - - -package mir.storage; - +package mir.storage; import multex.Failure; /** - * Expception Objekt fuer alle Fehler, die in der Speicherzugriffsschicht - * (mir.storage) auftauchen + * Exception for all occuring failures in the storage-layer + * @author idefix */ public class StorageObjectFailure extends Failure { /** @@ -55,25 +43,21 @@ public class StorageObjectFailure extends Failure { * @param e */ public StorageObjectFailure(Throwable e) { - super("",e); + super("", e); } - /** - * Leerer Konstruktor - */ - public StorageObjectFailure () { - super("A failure occured",null); - } + /** + * Standard constructor + */ + public StorageObjectFailure() { + super("A failure occured", null); + } - /** - * Konstruktor mit Nachricht - * @param String msg - */ - public StorageObjectFailure (String msg, Throwable e) { - super(msg, e); + /** + * Construktor with message + * @param String msg + */ + public StorageObjectFailure(String msg, Throwable e) { + super(msg, e); } } - - - - -- 2.11.0