diff --git a/genjava/.DS_Store b/genjava/.DS_Store new file mode 100644 index 00000000..4950ea96 Binary files /dev/null and b/genjava/.DS_Store differ diff --git a/genjava/FUTURE b/genjava/FUTURE new file mode 100644 index 00000000..9b21e203 --- /dev/null +++ b/genjava/FUTURE @@ -0,0 +1,61 @@ +Split-off: + +gj-csv +gj-xml +gj-scrape +gj-tools +gj-core +gj-mail +gj-beans + +REMOVE +- +src/java/com/generationjava/security + +gj-core 3.0 +----------- + +src/java/com/generationjava/compare +src/java/com/generationjava/random + +src/java/com/generationjava/collections + +src/java/com/generationjava/io/ +src/java/com/generationjava/io/find +src/java/com/generationjava/lang +src/java/com/generationjava/math - fold back into the old repo. useless +src/java/com/generationjava/net +src/java/com/generationjava/util + +src/java/com/generationjava/jdbc - does dbutils replace this? + + +gj-tools 1.0 +------------ +src/java/com/generationjava/tools +src/java/com/generationjava/net/WGet - Goes to Tools instance? + +gj-scrape 1.0 +------------- +src/java/com/generationjava/web +src/java/com/generationjava/scrape + +gj-csv 1.0 +---------- +src/java/com/generationjava/io/Csv + +gj-xml 1.0 +---------- +src/java/com/generationjava/io/xml + +gj-mail 1.0 +----------- +src/java/com/generationjava/mail + +gj-beans 1.0 +------------ +src/java/com/generationjava/beans + +gj-j2ee [ not core, yet ] +------- +src/java/com/generationjava/servlet diff --git a/genjava/LICENSE.txt b/genjava/LICENSE.txt new file mode 100644 index 00000000..38aecf65 --- /dev/null +++ b/genjava/LICENSE.txt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/genjava/gj-beans/project.properties b/genjava/gj-beans/project.properties new file mode 100644 index 00000000..56a44b4c --- /dev/null +++ b/genjava/gj-beans/project.properties @@ -0,0 +1,11 @@ +maven.repo.remote=http://www.osjava.org/maven/,http://www.ibiblio.org/maven/ + +maven.ui.navcol.background=#f4f8d8 +maven.ui.banner.background=#000066 +maven.ui.section.background=#000066 +maven.ui.subsection.background=#000066 +maven.xdoc.date = left +maven.xdoc.version = v${pom.currentVersion} +maven.ui.breadcrumbs.background=#f4f8d8 + +maven.xdoc.poweredby.image=maven-feather.png diff --git a/genjava/gj-beans/project.xml b/genjava/gj-beans/project.xml new file mode 100755 index 00000000..e9500e33 --- /dev/null +++ b/genjava/gj-beans/project.xml @@ -0,0 +1,37 @@ + + + ../project.xml + gj-beans + GenJava-Beans + 1.0 + 2002 + + + BeanViewer. Similar to Jakarta BeanUtils and thus deprecated in favour of that code. + + + BeanViewer + + + + gj-core + 3.0 + + + commons-lang + 2.0 + http://jakarta.apache.org/commons/lang.html + + + commons-collections + 2.1 + http://jakarta.apache.org/commons/collections.html + + + junit + 3.7 + + + + + diff --git a/genjava/gj-beans/src/java/com/generationjava/beans/AbstractBeanViewer.java b/genjava/gj-beans/src/java/com/generationjava/beans/AbstractBeanViewer.java new file mode 100644 index 00000000..cfd91ea6 --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/beans/AbstractBeanViewer.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.beans; + +import java.util.List; +import java.util.Enumeration; +import java.util.Iterator; + +import org.apache.commons.collections.CollectionUtils; + +/** + * Helps us deal with such wonderful things as array notation + * and object notation. Array notation may use associative array notation. + * + * @date 2001-06-14 + */ +abstract public class AbstractBeanViewer { + + /** + * Get the property of myBean with the name of the key's toString. + * + * The key may use dotted notation to imply a property in a property + * and array notation to get the nth property in a list of propertys. + */ + public Object get(Object key, Object myBean) { + if( key == null ) { + return null; + } + + if(myBean == null) { + return null; + } + + String name = key.toString(); + + BeanViewRuntime runtime = new BeanViewRuntime(); + runtime.pushObject(myBean); + + int idx = 0; + Object obj = myBean; + while( (idx = name.indexOf('.', idx)) != -1) { + String pre = name.substring(0, idx); + name = name.substring(idx+1); + if(obj != null) { + obj = handleGet(runtime, obj, pre); + runtime.pushObject(obj); + } else { + return null; + } + } + + return handleGet(runtime, obj, name); + } + + /** + * Give a bean, and a String name, get the property with that name + * from the bean. + * Does not handle dot notation, but does handle array notation + * and associative array notation. + */ + public Object handleGet(BeanViewRuntime runtime, Object bean, String name) { + // deal with array + int i = name.indexOf('['); + Object index = null; + if(i != -1) { + String pre = name.substring(i+1); + if(pre.endsWith("]")) { + pre = pre.substring(0, pre.length() -1); + } + try { + index = Integer.valueOf(pre); + } catch(NumberFormatException nfe) { + index = pre; + } + name = name.substring(0,i); + } + + // shouldn't be null + if(name.equals("")) { + return CollectionUtils.index(bean, index); + } else { + return invokeGet( runtime, bean, name, index ); + } + } + + /** + * Get a value from a bean with the specified name. + * If the bean is indexed, an int index is passed. Else it is -1. + * It is recommmended that implementors of this method use the + * index method to handle the array notation. + */ + abstract public Object invokeGet(BeanViewRuntime runtime, Object bean, String name, Object idx); + + public Object set(Object key, Object bean, Object value) { + if(key == null) { + return null; + } + + if(bean == null) { + return null; + } + + String name = key.toString(); + + int idx = name.lastIndexOf("."); + if(idx != -1) { + String pre = name.substring(0, idx); + String post = name.substring(idx+1); + Object parent = get(pre, bean); +// TODO: remove [] notation from name. +// equally, need to pass idx as an Object, so implies that +// invokeGet shuld have Object idx and so should index. + bean = parent; + name = post; + } + // call invokeGet to get the current value, then + // call invokeSet + invokeSet(null, bean, name, null, value); + + // return old value + return null; + } + + abstract public void invokeSet(BeanViewRuntime runtime, Object bean, String name, Object idx, Object value); + +} diff --git a/genjava/gj-beans/src/java/com/generationjava/beans/BeanImplProxy.java b/genjava/gj-beans/src/java/com/generationjava/beans/BeanImplProxy.java new file mode 100644 index 00000000..64b5cde0 --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/beans/BeanImplProxy.java @@ -0,0 +1,76 @@ +package com.generationjava.beans; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import com.generationjava.namespace.Namespace; +import com.generationjava.namespace.SimpleNamespace; + +import org.apache.commons.lang.StringUtils; + +public class BeanImplProxy implements InvocationHandler { + + public static Object newInstance(Class intfce) { + BeanImplProxy handler = new BeanImplProxy(intfce); + Class proxyClass = Proxy.getProxyClass( + intfce.getClassLoader(), + new Class[] { intfce } + ); + try { + return proxyClass.getConstructor( new Class[] { InvocationHandler.class } + ).newInstance(new Object[] { handler }); + } catch(NoSuchMethodException nsme) { + nsme.printStackTrace(); + } catch(SecurityException se) { + se.printStackTrace(); + } catch(InstantiationException ie) { + ie.printStackTrace(); + } catch(IllegalAccessException iae) { + iae.printStackTrace(); + } catch(InvocationTargetException ite) { + ite.printStackTrace(); + } + return null; + } + + private Class type; + private Namespace namespace; + + private BeanImplProxy(Class type) { + this.type = type; + this.namespace = new SimpleNamespace(); + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Class returnType = method.getReturnType(); + String name = method.getName(); + if(returnType == Void.TYPE) { + // test this + if(name.startsWith("set")) { + if(args.length == 1) { + String property = StringUtils.uncapitalise(name.substring(3)); + this.namespace.putValue(property, args[0]); + } + } + return null; + } + if(returnType == Class.class) { + if("getClass".equals(name)) { + // pretend to be this + return this.type; + } + } + if("toString".equals(name)) { + // try to output nicely + return BeansW.beanToString(proxy); + } + if(name.startsWith("get")) { + String property = StringUtils.uncapitalise(name.substring(3)); + return this.namespace.getValue(property); + } + return null; // ?? + } + +} diff --git a/genjava/gj-beans/src/java/com/generationjava/beans/BeanViewRuntime.java b/genjava/gj-beans/src/java/com/generationjava/beans/BeanViewRuntime.java new file mode 100644 index 00000000..82eda0ab --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/beans/BeanViewRuntime.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.beans; + +import java.util.LinkedList; +import java.util.Iterator; + +public class BeanViewRuntime { + + private LinkedList list; + + public BeanViewRuntime() { + list = new LinkedList(); + } + + public Iterator iterateUpwards() { + return list.iterator(); + } + + public void pushObject(Object obj) { + list.addFirst(obj); + } + + public Object parentObject() { + return list.getFirst(); + } + + public Object parentObject(int n) { + return list.get(n); + } + +} diff --git a/genjava/gj-beans/src/java/com/generationjava/beans/BeansW.java b/genjava/gj-beans/src/java/com/generationjava/beans/BeansW.java new file mode 100644 index 00000000..a3ed1ebc --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/beans/BeansW.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.beans; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +import com.generationjava.lang.ClassW; +import org.apache.commons.lang.NumberUtils; + +public class BeansW { + + static private java.text.DateFormat format = new java.text.SimpleDateFormat(); + + static public Object convert(Object value, Class toClass) { + System.err.println("ASKED TO CONVERT: "+value+" which is a "+value.getClass()+" to "+toClass); + if(toClass.equals(value.getClass())) { + return value; + } else + if(ClassW.classInstanceOf(toClass, "java.lang.String")) { + return value; + } else + if(ClassW.classInstanceOf(toClass, "java.lang.Integer") || + Integer.TYPE.equals(toClass) + ) { + return NumberUtils.createInteger(value.toString()); + } else + if(ClassW.classInstanceOf(toClass, "java.lang.Long") || + Long.TYPE.equals(toClass) + ) { + return NumberUtils.createLong(value.toString()); + } else + if(ClassW.classInstanceOf(toClass, "java.lang.Double") || + Double.TYPE.equals(toClass) + ) { + return NumberUtils.createDouble(value.toString()); + } else + if(ClassW.classInstanceOf(toClass, "java.lang.Number")) { + return NumberUtils.createNumber(value.toString()); + } else + if(ClassW.classInstanceOf(toClass, "java.util.Date")) { +// return DateW.parseString(value.toString()); + try { + return format.parse( value.toString() ); + } catch(java.text.ParseException pe) { + return value; + } + } else { + return value; + } + } + + static public String beanToString(Object bean) { + if(bean == null) { + return null; + } + Class clss = bean.getClass(); + StringBuffer text = new StringBuffer(); + try { + BeanInfo beaninfo = Introspector.getBeanInfo(clss); + PropertyDescriptor[] pd = beaninfo.getPropertyDescriptors(); + for(int i=0; i + +

+Provides reflective ability on JavaBeans. BeanComparator in com.generationjava.compare uses this and is very nice. com.generationjava.collections.BeanMap is also nice. +

+

+Jakarta Commons BeanUtils is pretty much the same as all this. This is cuter I think, but less mature. +

+ + diff --git a/genjava/gj-beans/src/java/com/generationjava/collections/BeanMap.java b/genjava/gj-beans/src/java/com/generationjava/collections/BeanMap.java new file mode 100644 index 00000000..44fa5797 --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/collections/BeanMap.java @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.collections; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import java.util.Map; +import java.util.HashMap; +import java.util.Collection; +import java.util.Set; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.collections.CollectionUtils; + +import com.generationjava.beans.AbstractBeanViewer; +import com.generationjava.beans.BeanViewRuntime; + +/** + * A Map which wraps a JavaBean. + * + * @date 2001-05-11 + */ +public class BeanMap extends AbstractBeanViewer implements Map { + + private Object myBean = null; + private Map pdCache = new HashMap(); + + /** + * Construct a BeanMap around the supplied Java Bean. + */ + public BeanMap(Object bean) { + myBean = bean; + try { + BeanInfo info = Introspector.getBeanInfo( myBean.getClass() ); + PropertyDescriptor[] pds = info.getPropertyDescriptors(); + for(int i=0; i 1) { + name += name.substring(1); + } + +/* + methodName = "get"+methodName; + + Method getMethod = null; + Class[] clss0 = new Class[0]; + Class[] clss = null; + try { + if(idx != -1) { + clss = new Class[1]; + clss[0] = Integer.TYPE; + } else { + clss = clss0; + } + getMethod = bean.getClass().getMethod(methodName, clss); + } catch(SecurityException se) { + } catch(NoSuchMethodException nsme) { + try { + if(clss != clss0) { + getMethod = bean.getClass().getMethod(methodName, clss0); + } + arrayLike = false; + } catch(SecurityException se2) { + } catch(NoSuchMethodException nsme2) { + } + } + + if(getMethod == null) { + return null; + } + try { + Object[] param = null; + if(arrayLike) { + param = new Object[1]; + param[0] = new Integer(idx); + } else { + param = new Object[0]; + } + Object obj = getMethod.invoke( bean, param ); +* / + Object obj = invokeGet( bean, name, index ); + obj = CollectionUtils.index(obj, index); + return obj; + /* + if( (obj instanceof Map) && (pre != null) ) { + return ((Map)obj).get(pre); + } else + if( (obj instanceof List) && (idx != -1) ) { + return ((List)obj).get(idx); + } else + if( (obj instanceof Object[]) && (idx != -1) ) { + return ((Object[])obj)[idx]; + } else { + return obj; + } + */ +/* + } catch(IllegalAccessException iae) { + return null; + } catch(IllegalArgumentException iae) { + return null; + } catch(InvocationTargetException ite) { + return null; + } +* / + } +*/ + /** + * Returns bean.get[idx] + */ + public Object invokeGet(BeanViewRuntime runtime, Object bean, String methodName, Object index) { + int idx = -1; + boolean arrayLike = (index instanceof Integer); + if(arrayLike) { + idx = ((Integer)index).intValue(); + } + methodName = "get"+methodName; + + Method getMethod = null; + Class[] clss0 = new Class[0]; + Class[] clss = null; + try { + if(arrayLike) { + clss = new Class[1]; + clss[0] = Integer.TYPE; + } else { + clss = clss0; + } + getMethod = bean.getClass().getMethod(methodName, clss); + } catch(SecurityException se) { + } catch(NoSuchMethodException nsme) { + try { + if(clss != clss0) { + getMethod = bean.getClass().getMethod(methodName, clss0); + } + arrayLike = false; + } catch(SecurityException se2) { + } catch(NoSuchMethodException nsme2) { + } + } + + if(getMethod == null) { + return null; + } + try { + Object[] param = null; + if(arrayLike) { + param = new Object[1]; + param[0] = new Integer(idx); + } else { + param = new Object[0]; + } + Object obj = getMethod.invoke( bean, param ); + obj = CollectionUtils.index(obj, idx); + + return obj; +// if( (obj instanceof Map) && (pre != null) ) { +// return ((Map)obj).get(pre); +// } else +// if( (obj instanceof List) && (idx != -1) ) { +// return ((List)obj).get(idx); +// } else +// if( (obj instanceof Object[]) && (idx != -1) ) { +// return ((Object[])obj)[idx]; +// } else { +// return obj; +// } + } catch(IllegalAccessException iae) { + return null; + } catch(IllegalArgumentException iae) { + return null; + } catch(InvocationTargetException ite) { + return null; + } + } + + public void invokeSet(BeanViewRuntime runtime, Object bean, String name, Object idx, Object value) { + } +} diff --git a/genjava/gj-beans/src/java/com/generationjava/compare/BeanComparator.java b/genjava/gj-beans/src/java/com/generationjava/compare/BeanComparator.java new file mode 100644 index 00000000..fd7bc629 --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/compare/BeanComparator.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.compare; + +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; + +import com.generationjava.beans.ReflectionBeanViewer; + +/** + * A Comparator for JavaBeans. Provide the name of the property to + * be compared with, and BeanComparator will deal with finding the + * property and comparing on it using ObjectComparator. + * + * Some examples are: + * "person" -> getPerson() + * "person.name" -> getPerson().getName() + * "person.addressMap.fred" -> getPerson().getAddressMap().get("fred") + * "person.phone[3]" -> getPerson().getPhone()[3] and + * getPerson().getPhone().get(3) (array and List) + */ +public class BeanComparator implements Comparator { + + static private Map beanComparatorRegistry = new HashMap(); + + /** + * Get a BeanComparator for the specified property. + */ + static public BeanComparator getInstance(String attrib) { + Object obj = beanComparatorRegistry.get(attrib); + if(obj == null) { + obj = new BeanComparator(attrib); + beanComparatorRegistry.put(attrib, obj); + } + return (BeanComparator)obj; + } + + private String attribute; + private HashMap cache; + private ReflectionBeanViewer bv = new ReflectionBeanViewer(); + private Comparator oc = new ObjectComparator(); + + public BeanComparator(String attrib) { + this.attribute = attrib; + } + + public void setComparator(Comparator comp) { + this.oc = comp; + } + + /** + * Do a Schwartzian transform precompile of all the values. + * Pattern from Perl. + */ + public void precompile(Collection col) { + caching(true); + Iterator iterator = col.iterator(); + while(iterator.hasNext()) { + Object bean = iterator.next(); + Object ret = bv.get(this.attribute, bean); + cache.put(bean, ret); + } + } + + /** + * Turn on caching. Akin to Perl's Orcish maneuver. + * Recalling this method will reset caching. + */ + public boolean caching(boolean b) { + boolean b2 = caching(); + this.cache = b?new HashMap():null; + return b2; + } + + /** + * Is caching on? + */ + public boolean caching() { + return (this.cache != null); + } + + public int compare(Object o1, Object o2) { + if(o1 == null) { + return 1; + } else + if(o2 == null) { + return -1; + } + + Object ret1 = null; + Object ret2 = null; + if(caching()) { + ret1 = cache.get(o1); + ret2 = cache.get(o2); + } + if(ret1 == null) { + ret1 = bv.get(this.attribute, o1); + } + if(ret2 == null) { + ret2 = bv.get(this.attribute, o2); + } + + return oc.compare(ret1, ret2); + } +} + diff --git a/genjava/gj-beans/src/java/com/generationjava/namespace/BeanNamespace.java b/genjava/gj-beans/src/java/com/generationjava/namespace/BeanNamespace.java new file mode 100644 index 00000000..e0b2eace --- /dev/null +++ b/genjava/gj-beans/src/java/com/generationjava/namespace/BeanNamespace.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.namespace; + +import java.util.Iterator; + +import com.generationjava.beans.ReflectionBeanViewer; + +/** + * A Bean namespace. It gets its value from a java-bean. + */ +public class BeanNamespace extends AbstractNamespace { + + private ReflectionBeanViewer myViewer; + private Object myBean; + + public BeanNamespace(Object bean) { + this.myViewer = new ReflectionBeanViewer(); + this.myBean = bean; + } + + public Object getBean() { + return this.myBean; + } + + /** + * Get a property from a bean. Dotted notation, array notation + * and associative array notation all apply. + */ + public Object getValue(String name) { + return myViewer.get(name,myBean); + } + + /** + * Unimplemented. + */ + public void putValue(String name, Object info) { + // bean-namespace's are read only for the moment. + } + + public Iterator iterateNames() { + // return the names + return null; + } + +} diff --git a/genjava/gj-csv/LICENSE.txt b/genjava/gj-csv/LICENSE.txt new file mode 100644 index 00000000..38aecf65 --- /dev/null +++ b/genjava/gj-csv/LICENSE.txt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/genjava/gj-csv/project.properties b/genjava/gj-csv/project.properties new file mode 100644 index 00000000..56a44b4c --- /dev/null +++ b/genjava/gj-csv/project.properties @@ -0,0 +1,11 @@ +maven.repo.remote=http://www.osjava.org/maven/,http://www.ibiblio.org/maven/ + +maven.ui.navcol.background=#f4f8d8 +maven.ui.banner.background=#000066 +maven.ui.section.background=#000066 +maven.ui.subsection.background=#000066 +maven.xdoc.date = left +maven.xdoc.version = v${pom.currentVersion} +maven.ui.breadcrumbs.background=#f4f8d8 + +maven.xdoc.poweredby.image=maven-feather.png diff --git a/genjava/gj-csv/project.xml b/genjava/gj-csv/project.xml new file mode 100755 index 00000000..cda9215b --- /dev/null +++ b/genjava/gj-csv/project.xml @@ -0,0 +1,23 @@ + + + ../project.xml + gj-csv + GenJava-CSV + 1.0 + 2002 + + + CSV component of GenJava-Core. Reads and writes CSV files. + + + CSV Reader/Writers + + + + junit + 3.7 + + + + + diff --git a/genjava/gj-csv/src/java/com/generationjava/io/Csv.java b/genjava/gj-csv/src/java/com/generationjava/io/Csv.java new file mode 100644 index 00000000..f63f7367 --- /dev/null +++ b/genjava/gj-csv/src/java/com/generationjava/io/Csv.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +// Csv.java +package com.generationjava.io; + +import java.io.IOException; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Properties; +import java.util.Set; + +public class Csv { + + static public char FIELD_DELIMITER = ','; + static public char BLOCK_DELIMITER = '\n'; + + private LinkedList list = new LinkedList(); + private String[] headers; + + public Csv(CsvReader reader) throws IOException { + this.headers = reader.readLine(); + + String[] line = null; + + // suck in the file. + // TODO: What's the optimal structure for this + while( (line = reader.readLine()) != null) { + list.add(line); + } + } + + // get all of the unique fields for this header + public String[] getAll(String header) { + HashSet values = new HashSet(); + int idx = getHeaderIndex(header); + Iterator iterator = list.iterator(); + while(iterator.hasNext()) { + values.add( ((String[])iterator.next())[idx]); + } + return (String[])values.toArray(new String[0]); + } + + private int getHeaderIndex(String header) { + for(int i=0;i + + ../project.xml + gj-mail + GenJava-Mail + 1.0 + 2002 + + + Mail component of GenJava-Core. Adds some helper functionality around JavaMail. + + + Mail helpers + + + + javamail + 1.2 + + + gj-core + 3.0 + + + commons-lang + 2.0 + http://jakarta.apache.org/commons/lang.html + + + junit + 3.7 + + + + + diff --git a/genjava/gj-mail/src/java/com/generationjava/mail/MBoxMimeMessage.java b/genjava/gj-mail/src/java/com/generationjava/mail/MBoxMimeMessage.java new file mode 100644 index 00000000..2a5398dc --- /dev/null +++ b/genjava/gj-mail/src/java/com/generationjava/mail/MBoxMimeMessage.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.mail; + +import java.io.InputStream; + +import javax.mail.*; +import javax.mail.internet.*; + +import com.generationjava.collections.CollectionsW; +import com.generationjava.io.StreamW; +import org.apache.commons.lang.StringUtils; + +// one other idea is to allow a body only to be passed in, +// with the headers already set within that. + +// TODO: +// Attachment: 1. , +// 2. ..... +public class MBoxMimeMessage extends MimeMessage { + + private static java.text.DateFormat format = new java.text.SimpleDateFormat(); + + public MBoxMimeMessage(Session session) { + super(session); + } + + public void setText(String body) throws MessagingException { + parseMBox(this, body); + } + + public void parseMBox(Part mimePart, String body) throws MessagingException { +// System.err.println("BODY["+body+"]"); +// Date: 26 Feb 2001 00:11:05 +0000 +// From: +// To: +// Subject: +// Content-Type: TEXT/PLAIN; charset=US-ASCII +// then a blank line. How to handle multi?? + +// multi is handled by: +// Content-Type: multipart/alternative; boundary="FLAG" +// --FLAG +// Content-Type: text/plain; charset="iso-8859-1" +// ....texxt... +// Content-Type: text/html; charset="iso-8859-1" +// Content-Transfer-Encoding: quoted-printable + + // split lines + String[] lines = StringUtils.split(body, "\n"); + + // pre process lines so that any headers that are split + // over a newline are joined + + int sz = lines.length; + String multipart = null; + String mimeType = null; + String subtype = null; + int i=0; // kept for later + for(; i [content-type] "comment", + String[] attachments = StringUtils.split(value, ","); + Multipart multi = new MimeMultipart(); + mimePart.setContent(multi); + for(int k=0; k + + ../project.xml + gj-scrape + GenJava-Scrape + 1.0 + 2002 + + + Simple scraping component of GenJava-Core. + + + Scraper APIs + + + + junit + 3.7 + + + commons-lang + 2.0 + http://jakarta.apache.org/commons/lang.html + + + + + diff --git a/genjava/gj-scrape/src/java/com/generationjava/scrape/HtmlScraper.java b/genjava/gj-scrape/src/java/com/generationjava/scrape/HtmlScraper.java new file mode 100644 index 00000000..bb18d870 --- /dev/null +++ b/genjava/gj-scrape/src/java/com/generationjava/scrape/HtmlScraper.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.scrape; + +import java.io.InputStream; +import java.io.IOException; +import java.util.LinkedList; + +import org.apache.commons.lang.StringUtils; +//import com.generationjava.net.UrlW; +import com.generationjava.web.HtmlW; + +/// simple system in. need to now consider the move methods. +/// then need to make sure the get method obeys internal +/// rules. ie) if given td.a and u find td.td, should then look +/// at that td? I guess so. Just as long as a tag doesn't span +/// another that it's not allowed to. + +// need to be able to say: move to b.class=blah and b=foo + +/// Add a moveback(String tag) method +/// Add a getContent(int i) method to get untagged blocks of text +public class HtmlScraper { + + /* + static public void main(String[] args) throws IOException { + HtmlScraper scraper = new HtmlScraper(); + scraper.scrape(UrlW.openUrlStream("http://www.yandell.org")); + System.err.println(scraper.get("TITLE").trim()); + System.err.println(scraper.get("HEAD.TITLE").trim()); + System.err.println(scraper.get("HTML.HEAD.TITLE").trim()); + System.err.println(scraper.get("HTML.HEAD.META[name]")); + while(scraper.move("LI")) { + System.err.println(scraper.get("A[HREF]")); + } + System.err.println(scraper.get("LI.I")); + } + */ + + private String data; + private String page; + + public HtmlScraper() { + } + + public int getIndex() { + return this.page.length() - this.data.length(); + } + + /** + * @deprecated Do the work yourself and get the String + */ + public void scrape(InputStream in) { + try { + page = ""+getContent(in); + reset(); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + } + + public void scrape(String text) { + if(text.startsWith("http://")) { + throw new RuntimeException("Text starts with http://. This could be bad. "); + } + this.page = text; + reset(); + } + + /** + * Move back to the start of the page. + */ + public void reset() { + this.data = this.page; + } + + /** + * Move to the specified tag. + */ + // This needs to be case-insensitive + public boolean move(String tag) { + int idx = HtmlW.getIndexOpeningTag(tag, data.substring(1)); + if(idx == -1) { + return false; + } else { + idx++; + } + this.data = data.substring(idx); + return true; + } + + /** + * Helper method. + * Move a number of tags. + */ + public boolean move(String tag, int sz) { + for(int i=0; i< sz; i++) { + if(!move(tag)) { + return false; + } + } + return true; + } + + // finds any tag with name=value attribute. Need to be able + // to specify the tag really, and also the same for a value. + // really we need a generic search method? :) + // get this value, is it this. if not, find next. + + // Tricky. name needs to be case-insensitive, value needs + // to not be. + public boolean moveToTagWith(String name, String value) { + int idx = this.data.indexOf(name+"=\""+value+"\""); + if(idx == -1) { + idx = this.data.indexOf(name+"="+value); + } + if(idx == -1) { + idx = this.data.indexOf(name+"='"+value+"'"); + } + if(idx == -1) { + return false; + } else { + idx = this.data.lastIndexOf("<", idx); + this.data = data.substring(idx); + return true; + } + } + + // moveTo a[href], www.yandell.org + public boolean moveTo(String get, String value) { + HtmlScraper scraper = new HtmlScraper(); + scraper.scrape(this.data); + int count = 1; + while(true) { + boolean found = scraper.move(get); + if(!found) { + return false; + } + String chunk = scraper.get(get); + if( (chunk == null) || (chunk.equals("")) ) { + return false; + } + if(chunk.equals(value)) { + move(get, count); + break; + } else { + count++; + } + } + return true; + } + + /** + * Move to a specified piece of text. + */ + public boolean moveToText(String text) { + int idx = this.data.indexOf(text); + if(idx == -1) { + return false; + } else { + this.data = data.substring(idx); + return true; + } + } + + /** + * Move to a specified comment. The parameter should + * not contain the HTML comment syntax. + */ + public boolean moveToComment(String comment) { + int idx = this.data.indexOf(comment); + if(idx == -1) { + return false; + } else { + idx = data.lastIndexOf(" + +

+ A HtmlScraping library. Well really an Xml one. +

+ + diff --git a/genjava/gj-scrape/src/java/com/generationjava/web/HtmlW.java b/genjava/gj-scrape/src/java/com/generationjava/web/HtmlW.java new file mode 100644 index 00000000..6c5258e1 --- /dev/null +++ b/genjava/gj-scrape/src/java/com/generationjava/web/HtmlW.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.web; + +import org.apache.commons.lang.StringUtils; + +/** + * HTML helping static methods. + */ +public class HtmlW { + + /** + * Place <br>'s before each newline. + */ + static public String nl2br(String str) { + return StringUtils.replace(str, "\n", "
\n"); + } + + + /// TODO: escape all html char entitie + static public String escapeHtml(String str) { + // handles & < > " ' + str = XmlW.escapeXml(str); + + str = StringUtils.replace(str, "\u00a0", " "); + str = StringUtils.replace(str, "\u00a1", "¡"); + str = StringUtils.replace(str, "\u00a2", "¢"); + str = StringUtils.replace(str, "\u00a3", "£"); + str = StringUtils.replace(str, "\u00a4", "¤"); + str = StringUtils.replace(str, "\u00a5", "¥"); + str = StringUtils.replace(str, "\u00a6", "¦"); + str = StringUtils.replace(str, "\u00a7", "§"); + str = StringUtils.replace(str, "\u00a8", "¨"); + str = StringUtils.replace(str, "\u00a9", "©"); + str = StringUtils.replace(str, "\u00aa", "ª"); + str = StringUtils.replace(str, "\u00ab", "«"); + str = StringUtils.replace(str, "\u00ac", "¬"); + str = StringUtils.replace(str, "\u00ad", "­"); + str = StringUtils.replace(str, "\u00ae", "®"); + str = StringUtils.replace(str, "\u00af", "¯"); +/* +° +&#176 +± +&#177 +² +&#178 +³ +&#179 +´ +&#180 +µ +&#181 +¶ +&#182 +· +&#183 +¸ +&#184 +¹ +&#185 +º +&#186 +» +&#187 +¼ +&#188 +½ +&#189 +¾ +&#190 +¿ +&#191 +À +&#192 +Á +&#193 +Â +&#194 +Ã +&#195 +Ä +&#196 +Å +&#197 +Æ +&#198 +Ç +&#199 +È +&#200 +É +&#201 +Ê +&#202 +Ë +&#203 +Ì +&#204 +Í +&#205 +Î +&#206 +Ï +&#207 +*/ + + return str; + } + + /** + * Remove any html tags from a String. + */ + static public String removeHtml(String str) { + int sz = str.length(); + StringBuffer buffer = new StringBuffer(sz); + boolean inString = false; + boolean inTag = false; + for(int i=0; i') { + inTag = false; + } + if(!inTag) { + buffer.append(ch); + } + } + return buffer.toString(); + } + + //------------------------------------------------------------- + // Variants of the XmlW methods that work on case-insensitivity + //------------------------------------------------------------- + static public int getIndexOpeningTag(String tag, String text) { + return XmlW.getIndexOpeningTag(tag.toLowerCase(), text.toLowerCase() ); + } + static public int getIndexClosingTag(String tag, String text) { + return XmlW.getIndexClosingTag(tag.toLowerCase(), text.toLowerCase() ); + } + + // Copy of XmlW at the moment + static public String getContent(String tag, String text) { + int idx = HtmlW.getIndexOpeningTag(tag, text); +// System.err.println("IDX"+text+": "+idx); + if(idx == -1) { + return ""; + } + text = text.substring(idx); + int end = HtmlW.getIndexClosingTag(tag, text); +// System.err.println("END[]: "+end); + idx = text.indexOf('>'); +// System.err.println("EDX["+text+"]: "+idx); + if(idx == -1) { + return ""; + } + return text.substring(idx+1, end); + } + + // Copies of XmlW. Need to merge these. + static public String getAttribute(String attribute, String text) { + return getAttribute(attribute, text, 0); + } + static public String getAttribute(String attribute, String text, int idx) { + int close = text.indexOf(">", idx); + int attrIdx = text.toLowerCase().indexOf(attribute.toLowerCase()+"=\"", idx); + if(attrIdx == -1) { + return null; + } + if(attrIdx > close) { + return null; + } + int attrStartIdx = attrIdx + attribute.length() + 2; + int attrCloseIdx = text.indexOf("\"", attrStartIdx); + if(attrCloseIdx > close) { + return null; + } + return XmlW.unescapeXml(text.substring(attrStartIdx, attrCloseIdx)); + } + +} diff --git a/genjava/gj-scrape/src/java/com/generationjava/web/XmlW.java b/genjava/gj-scrape/src/java/com/generationjava/web/XmlW.java new file mode 100644 index 00000000..0af31f88 --- /dev/null +++ b/genjava/gj-scrape/src/java/com/generationjava/web/XmlW.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.web; + +import org.apache.commons.lang.StringUtils; + +/** + * XML helping static methods. + */ +final public class XmlW { + + static public String escapeXml(String str) { + str = StringUtils.replace(str,"&","&"); + str = StringUtils.replace(str,"<","<"); + str = StringUtils.replace(str,">",">"); + str = StringUtils.replace(str,"\"","""); + str = StringUtils.replace(str,"'","'"); + return str; + } + + static public String unescapeXml(String str) { + str = StringUtils.replace(str,"&","&"); + str = StringUtils.replace(str,"<","<"); + str = StringUtils.replace(str,">",">"); + str = StringUtils.replace(str,""","\""); + str = StringUtils.replace(str,"'","'"); + return str; + } + + /** + * Remove any xml tags from a String. + * Same as HtmlW's method. + */ + static public String removeXml(String str) { + int sz = str.length(); + StringBuffer buffer = new StringBuffer(sz); + boolean inString = false; + boolean inTag = false; + for(int i=0; i') { + inTag = false; + continue; + } + if(!inTag) { + buffer.append(ch); + } + } + return buffer.toString(); + } + + static public String getContent(String tag, String text) { + int idx = XmlW.getIndexOpeningTag(tag, text); + if(idx == -1) { + return ""; + } + text = text.substring(idx); + int end = XmlW.getIndexClosingTag(tag, text); + idx = text.indexOf('>'); + if(idx == -1) { + return ""; + } + return text.substring(idx+1, end); + } + + static public int getIndexOpeningTag(String tag, String text) { + return getIndexOpeningTag(tag, text, 0); + } + static private int getIndexOpeningTag(String tag, String text, int start) { + // consider whitespace? + int idx = text.indexOf("<"+tag, start); + if(idx == -1) { + return -1; + } + char next = text.charAt(idx+1+tag.length()); + if( (next == '>') || Character.isWhitespace(next) ) { + return idx; + } else { + return getIndexOpeningTag(tag, text, idx+1); + } + } + + // Pass in "para" and a string that starts with + // and it will return the index of the matching + // It assumes well-formed xml. Or well enough. + static public int getIndexClosingTag(String tag, String text) { + return getIndexClosingTag(tag, text, 0); + } + static public int getIndexClosingTag(String tag, String text, int start) { + String open = "<"+tag; + String close = ""; +// System.err.println("OPEN: "+open); +// System.err.println("CLOSE: "+close); + int closeSz = close.length(); + int nextCloseIdx = text.indexOf(close, start); +// System.err.println("first close: "+nextCloseIdx); + if(nextCloseIdx == -1) { + return -1; + } + int count = StringUtils.countMatches(text.substring(start, nextCloseIdx), open); +// System.err.println("count: "+count); + if(count == 0) { + return -1; // tag is never opened + } + int expected = 1; + while(count != expected) { + nextCloseIdx = text.indexOf(close, nextCloseIdx+closeSz); + if(nextCloseIdx == -1) { + return -1; + } + count = StringUtils.countMatches(text.substring(start, nextCloseIdx), open); + expected++; + } + return nextCloseIdx; + } + + static public String getAttr(String text, String attribute) { + return getAttribute(attribute, text); + } + static public String getAttr(String text, String attribute, int idx) { + return getAttribute(attribute, text, idx); + } + + /** + * @deprecated because the parameters are the wrong way + */ + static public String getAttribute(String attribute, String text) { + return getAttribute(attribute, text, 0); + } + /** + * @deprecated because the parameters are the wrong way + */ + static public String getAttribute(String attribute, String text, int idx) { + int close = text.indexOf(">", idx); + int attrIdx = text.indexOf(attribute+"=\"", idx); + if(attrIdx == -1) { + return null; + } + if(attrIdx > close) { + return null; + } + int attrStartIdx = attrIdx + attribute.length() + 2; + int attrCloseIdx = text.indexOf("\"", attrStartIdx); + if(attrCloseIdx > close) { + return null; + } + return unescapeXml(text.substring(attrStartIdx, attrCloseIdx)); + } + +} diff --git a/genjava/gj-scrape/src/test/com/generationjava/scrape/HtmlScraperTest.java b/genjava/gj-scrape/src/test/com/generationjava/scrape/HtmlScraperTest.java new file mode 100644 index 00000000..0a88379f --- /dev/null +++ b/genjava/gj-scrape/src/test/com/generationjava/scrape/HtmlScraperTest.java @@ -0,0 +1,50 @@ +package com.generationjava.scrape; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +public class HtmlScraperTest extends TestCase { + + public final String TEST_PAGE = "
FOO
"; + + public HtmlScraperTest(String name) { + super(name); + } + + //----------------------------------------------------------------------- + // To test: + // HtmlScraper()->scrape(..)->get/move etc + + public void testScrape() { + HtmlScraper scraper = new HtmlScraper(); + scraper.scrape(TEST_PAGE); + assertEquals( "FOO", scraper.get("td") ); + } + + public void testScrapeAttribute() { + HtmlScraper scraper = new HtmlScraper(); + scraper.scrape(TEST_PAGE); + assertEquals( "ffffff", scraper.get("table[bgcolor]") ); + } + + public void testCaseInsensitive() { + HtmlScraper scraper = new HtmlScraper(); + scraper.scrape(TEST_PAGE); + assertEquals( "FOO", scraper.get("TD") ); + assertEquals( "FOO", scraper.get("Td") ); + assertEquals( "FOO", scraper.get("tD") ); + assertEquals( "FOO", scraper.get("td") ); + } + + public void testCaseInsensitiveAttribute() { + HtmlScraper scraper = new HtmlScraper(); + scraper.scrape(TEST_PAGE); + assertEquals( "ffffff", scraper.get("TABLE[bgcolor]") ); + assertEquals( "ffffff", scraper.get("TABLE[BGCOLOR]") ); + assertEquals( "ffffff", scraper.get("table[BGCOLOR]") ); + assertEquals( "ffffff", scraper.get("table[bgcolor]") ); + } + +} diff --git a/genjava/gj-scrape/src/test/com/generationjava/web/XmlWTest.java b/genjava/gj-scrape/src/test/com/generationjava/web/XmlWTest.java new file mode 100644 index 00000000..ddcefd88 --- /dev/null +++ b/genjava/gj-scrape/src/test/com/generationjava/web/XmlWTest.java @@ -0,0 +1,27 @@ +package com.generationjava.web; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +public class XmlWTest extends TestCase { + + public XmlWTest(String name) { + super(name); + } + + //----------------------------------------------------------------------- + // To test: + // XmlW.removeXml + // XmlW.getContent + + public void testRemove() { + assertEquals( "FOO", XmlW.removeXml("FOO") ); + assertEquals( "FOO", XmlW.removeXml("FOO") ); + assertEquals( "FOO", XmlW.removeXml("FOO") ); + assertEquals( "FOO", XmlW.removeXml("FOO") ); + assertEquals( "", XmlW.removeXml("") ); + } + +} diff --git a/genjava/gj-servlet/project.properties b/genjava/gj-servlet/project.properties new file mode 100644 index 00000000..56a44b4c --- /dev/null +++ b/genjava/gj-servlet/project.properties @@ -0,0 +1,11 @@ +maven.repo.remote=http://www.osjava.org/maven/,http://www.ibiblio.org/maven/ + +maven.ui.navcol.background=#f4f8d8 +maven.ui.banner.background=#000066 +maven.ui.section.background=#000066 +maven.ui.subsection.background=#000066 +maven.xdoc.date = left +maven.xdoc.version = v${pom.currentVersion} +maven.ui.breadcrumbs.background=#f4f8d8 + +maven.xdoc.poweredby.image=maven-feather.png diff --git a/genjava/gj-servlet/project.xml b/genjava/gj-servlet/project.xml new file mode 100644 index 00000000..9be33877 --- /dev/null +++ b/genjava/gj-servlet/project.xml @@ -0,0 +1,32 @@ + + + ../project.xml + gj-servlet + GenJava-Servlet + 1.0 + 2002 + + + Servlet Components + + + Servlet Components + + + + servletapi + 2.3 + + + commons-collections + 2.1 + http://jakarta.apache.org/commons/collections.html + + + gj-core + 3.0 + + + + + diff --git a/genjava/gj-servlet/src/java/com/generationjava/namespace/ServletNamespace.java b/genjava/gj-servlet/src/java/com/generationjava/namespace/ServletNamespace.java new file mode 100644 index 00000000..6e13212e --- /dev/null +++ b/genjava/gj-servlet/src/java/com/generationjava/namespace/ServletNamespace.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.namespace; + +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * A servlet implementation of a Namespace. + * The request overrides the session. + */ +public class ServletNamespace extends AbstractNamespace { + + private HttpServletRequest request; + private HttpSession session; + + public ServletNamespace(HttpServletRequest request) { + this(request,null); + } + + public ServletNamespace(HttpServletRequest request, HttpSession session) { + this.request = request; + this.session = session; + } + + public Object getValue(String name) { + Object val = this.request.getAttribute(name); + if(val != null) { + return val; + } + + val = this.request.getParameter(name); + if(val != null) { + return val; + } + + if(this.session != null) { + val = this.session.getAttribute(name); + } + + return val; + } + + public void putValue(String name, Object info) { + this.request.setAttribute(name, info); + } + + public Iterator iterateNames() { + return null; + // iterate the null thingies + } + +} diff --git a/genjava/gj-servlet/src/java/com/generationjava/servlet/FileSystemServlet.java b/genjava/gj-servlet/src/java/com/generationjava/servlet/FileSystemServlet.java new file mode 100644 index 00000000..f5bfe14e --- /dev/null +++ b/genjava/gj-servlet/src/java/com/generationjava/servlet/FileSystemServlet.java @@ -0,0 +1,85 @@ +package com.generationjava.servlet; + +import java.io.IOException; +import java.io.File; +import java.io.Writer; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletRequest; + +import com.generationjava.io.find.FileFinder; +import com.generationjava.io.find.Finder; + +public class FileSystemServlet extends HttpServlet { + + public void doGet(HttpServletRequest request, + HttpServletResponse response) + throws ServletException, IOException + { + ServletConfig config = getServletConfig(); + + // the root of the file-system + String root = config.getInitParameter("root"); + + // pattern of files to consider + String filePattern = config.getInitParameter("file-pattern"); + // pattern of dirs to consider + String dirsPattern = config.getInitParameter("dirs-pattern"); + // also ones to exclude?? + + // a properties file mapping a mime type to a java class + // to display it. Must extend display(file). + String mimeUrl = config.getInitParameter("mime"); + + // use getResource to load mime mapping. FileW. + + Writer out = response.getWriter(); + out.write("root="+root); + out.write("
"); + out.write("file-pattern="+filePattern); + out.write("
"); + out.write("dirs-pattern="+dirsPattern); + out.write("
"); + out.write("mime="+mimeUrl); + out.write("
"); + + // if no request passed in, then run on root. + String target = request.getParameter("target"); + /* + if(target == null) { + target = root; + } else { + // SECURITY. ISH. + target = root + target; + } + */ + target = root; + + // open request-target as a directory. + Finder finder = new FileFinder(); + File file = new File(target); + + String[] found = finder.find(file); + for(int i=0; i"); + } + + // if request-target == directory + // get all files in the directory that match pattern? + // Ask each displayer to do an iconDisplay for each one. + // show on a html page as clickable icons. + // if request-target = a file. + // ask its displayer to show it in long form. + + // handle the concept of a file-writing. + // maybe make an applet front end rather than browser someday. + // offer multiple views etc. + + } + +} diff --git a/genjava/gj-servlet/src/java/com/generationjava/servlet/RequestMap.java b/genjava/gj-servlet/src/java/com/generationjava/servlet/RequestMap.java new file mode 100644 index 00000000..ccfb80d6 --- /dev/null +++ b/genjava/gj-servlet/src/java/com/generationjava/servlet/RequestMap.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.servlet; + +import java.util.Enumeration; +import java.util.Map; +import java.util.HashMap; + +import javax.servlet.ServletRequest; + +import org.apache.commons.collections.ProxyMap; + +/** + * @deprecated as not that special. Gone in 3.0. + */ +public class RequestMap extends ProxyMap { + + public RequestMap(ServletRequest request) { + super(new HashMap()); + Map map = request.getParameterMap(); + putAll(map); + + /* + Enumeration enum = request.getAttributeNames(); + while(enum.hasMoreElements()) { + String name = (String)enum.nextElement(); + + String[] strings = request.getParameterValues(name); + int sz = strings.length; + for(int i=0; i + +

+ Helpers for javax.servlet. +

+ + diff --git a/genjava/gj-servlet/src/java/com/generationjava/taglib/AbstractBodyTag.java b/genjava/gj-servlet/src/java/com/generationjava/taglib/AbstractBodyTag.java new file mode 100644 index 00000000..487e5d62 --- /dev/null +++ b/genjava/gj-servlet/src/java/com/generationjava/taglib/AbstractBodyTag.java @@ -0,0 +1,61 @@ +package com.generationjava.taglib; + +import java.io.IOException; +import java.io.StringWriter; + +import java.util.Properties; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.tagext.BodyTagSupport; + +/** + * Abstract class for the Taglibs. + * It has a param ability which binds to a generic ParamTag. + * + * @author bayard@generationjava.com + * @version 0.1, 20011028 + */ +abstract public class AbstractBodyTag extends BodyTagSupport { + + private Properties params; + + /** + * Empty constructor. Initialises the attributes. + */ + public AbstractBodyTag() { + initAttributes(); + } + + // code to handle adding params.. + /** + * Set a param. + */ + public void putParam(String name, String value) { + if(params == null) { + params = new Properties(); + } + params.put(name, value); + } + + /** + * Get a param out. + */ + public String getParam(String name) { + if(params == null) { + return null; + } + return params.getProperty(name); + } + + /** + * Initialise any properties to default values. + * This method is called upon construction. + * This is a default empty implementation. + */ + public void initAttributes() { + params.clear(); + } + +} diff --git a/genjava/gj-servlet/src/java/com/generationjava/taglib/AbstractStringBodyTag.java b/genjava/gj-servlet/src/java/com/generationjava/taglib/AbstractStringBodyTag.java new file mode 100644 index 00000000..2a12f35f --- /dev/null +++ b/genjava/gj-servlet/src/java/com/generationjava/taglib/AbstractStringBodyTag.java @@ -0,0 +1,66 @@ +package com.generationjava.taglib; + +import java.io.IOException; +import java.io.StringWriter; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.PageContext; + +/** + * Abstract class for the Taglibs. + * It handles the JSP taglib side of things and calls abstract + * protected methods to delegate the actual body functionality. + * + * @author bayard@generationjava.com + * @version 0.1, 20011028 + */ +abstract public class AbstractStringBodyTag extends AbstractBodyTag { + + /** + * Empty constructor. + */ + public AbstractStringBodyTag() { + super(); + } + + /** + * Handles the manipulation of the String tag, + * evaluating the body of the tag. The evaluation + * is delegated to the actOnBody(String) method + * and then the initAttributes() method is called. + */ + public int doEndTag() throws JspException { + + if( (bodyContent == null) ) { + return SKIP_BODY; + } + String text = ""; + if(bodyContent != null) { + StringWriter body = new StringWriter(); + try { + bodyContent.writeOut(body); + text = body.toString(); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + } + JspWriter writer = pageContext.getOut(); + try { + actOnBody(text); + initAttributes(); + } catch (IOException e) { + throw new JspException(e.toString()); + } + + return (SKIP_BODY); + } + + /** + * Perform an operation on the passed in String. + * + * @param str String to be manipulated + */ + abstract public void actOnBody(String str) throws IOException; + +} diff --git a/genjava/gj-servlet/src/java/com/generationjava/taglib/ParamTag.java b/genjava/gj-servlet/src/java/com/generationjava/taglib/ParamTag.java new file mode 100644 index 00000000..922340ab --- /dev/null +++ b/genjava/gj-servlet/src/java/com/generationjava/taglib/ParamTag.java @@ -0,0 +1,52 @@ +package com.generationjava.taglib; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.tagext.TagSupport; + +/** + * + * + * @author bayard@generationjava.com + * @version 0.1, 20011030 + */ +public class ParamTag extends TagSupport { + + private String name; + private String value; + + /** + * Empty constructor. + */ + public ParamTag() { + super(); + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * Initialise any properties to default values. + */ + public void initAttributes() { + } + + /// TODO: Implement its doing method. This would look at its + /// parent, and if it is of type AbstractBodyTag, then it + /// puts itself into the tag. Maybe use an Interface instead. + +} diff --git a/genjava/gj-tools/LICENSE.txt b/genjava/gj-tools/LICENSE.txt new file mode 100644 index 00000000..38aecf65 --- /dev/null +++ b/genjava/gj-tools/LICENSE.txt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/genjava/gj-tools/project.properties b/genjava/gj-tools/project.properties new file mode 100644 index 00000000..56a44b4c --- /dev/null +++ b/genjava/gj-tools/project.properties @@ -0,0 +1,11 @@ +maven.repo.remote=http://www.osjava.org/maven/,http://www.ibiblio.org/maven/ + +maven.ui.navcol.background=#f4f8d8 +maven.ui.banner.background=#000066 +maven.ui.section.background=#000066 +maven.ui.subsection.background=#000066 +maven.xdoc.date = left +maven.xdoc.version = v${pom.currentVersion} +maven.ui.breadcrumbs.background=#f4f8d8 + +maven.xdoc.poweredby.image=maven-feather.png diff --git a/genjava/gj-tools/project.xml b/genjava/gj-tools/project.xml new file mode 100644 index 00000000..9e0b9a08 --- /dev/null +++ b/genjava/gj-tools/project.xml @@ -0,0 +1,42 @@ + + + ../project.xml + gj-tools + GenJava-Tools + 1.0 + 2002 + + + A Tools API to make it simpler to write command line tools. + + + Tools API + + + + junit + 3.7 + + + commons-lang + 2.0 + http://jakarta.apache.org/commons/lang.html + + + commons-cli + 1.0 + http://jakarta.apache.org/commons/cli/ + + + commons-collections + 2.1 + http://jakarta.apache.org/commons/collections.html + + + gj-core + 3.0 + + + + + diff --git a/genjava/gj-tools/src/java/com/generationjava/net/WGet.java b/genjava/gj-tools/src/java/com/generationjava/net/WGet.java new file mode 100644 index 00000000..c31ecbc9 --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/net/WGet.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.net; + +import java.net.URL; +import java.net.MalformedURLException; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; + +/** + * Simple class allowing URLs to be obtained. + */ +public class WGet { + + // full url: http://www.generationjava.com/ + /** + * Provide a string url and it downloads the contents at + * that url. + */ + public String downloadPage(String urlStr) { + if(urlStr.indexOf("http://") == -1) { + urlStr = "http://"+urlStr; + } + StringBuffer sb = new StringBuffer(); + URL url = null; + try { + url = new URL(urlStr); + } catch(MalformedURLException mue) { + System.err.println("Had nasty url: "+urlStr); + mue.printStackTrace(); + return ""; + } + try { + InputStream is = url.openStream(); + BufferedReader bis = new BufferedReader(new InputStreamReader(is)); + String line = null; + while( (line = bis.readLine()) != null) { + sb.append(line); + } + } catch(IOException ioe) { + System.err.println("Had problems with: "+urlStr); + ioe.printStackTrace(); + } + return sb.toString(); + } +} diff --git a/genjava/gj-tools/src/java/com/generationjava/tools/AbstractTool.java b/genjava/gj-tools/src/java/com/generationjava/tools/AbstractTool.java new file mode 100644 index 00000000..c6dc3895 --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/tools/AbstractTool.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.tools; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.PosixParser; +import org.apache.commons.cli.PatternOptionBuilder; +import org.apache.commons.cli.ParseException; + +import org.apache.commons.lang.exception.NestableRuntimeException; + +abstract public class AbstractTool implements Tool { + + public CommandLine getCArgs(String flags, String[] args) { + try { + return new PosixParser().parse(PatternOptionBuilder.parsePattern(flags), args); + } catch(ParseException pe) { + throw new NestableRuntimeException(pe); + } + } + + abstract public void runTool(String[] args) throws ToolException; + +} diff --git a/genjava/gj-tools/src/java/com/generationjava/tools/CommandLineToolRunner.java b/genjava/gj-tools/src/java/com/generationjava/tools/CommandLineToolRunner.java new file mode 100644 index 00000000..6f7d9e05 --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/tools/CommandLineToolRunner.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.tools; + +import com.generationjava.lang.ClassW; + +public class CommandLineToolRunner { + + public CommandLineToolRunner() { + } + + public boolean runTool(Class clss, String[] args) { + Object obj = ClassW.createObject(clss); + if(obj instanceof Tool) { + return runTool((Tool)obj, args); + } else { + System.err.println("Class "+clss.getName()+" is not an instance of com.generationjava.tools.Tool"); + return false; + } + } + public boolean runTool(Tool tool, String[] args) { + try { + tool.runTool(args); + return true; + } catch(ToolException te) { + System.err.println(te.getMessage()); + return false; + } + } + +} diff --git a/genjava/gj-tools/src/java/com/generationjava/tools/Run.java b/genjava/gj-tools/src/java/com/generationjava/tools/Run.java new file mode 100644 index 00000000..77c04f69 --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/tools/Run.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.tools; + +import com.generationjava.collections.CollectionsW; +import com.generationjava.lang.ClassW; +import org.apache.commons.lang.StringUtils; +import com.generationjava.util.PropertiesLoader; +import java.util.Properties; + +/** + * A class which runs tools. + */ +public class Run { + + static public void main(String[] strs) { + /* + PropertiesLoader pl = new PropertiesLoader(); + Properties props = pl.findProperties("com/generationjava/test/test.properties"); + if(props != null) { + String location = props.getProperty("scaffold.package"); + if (strs[0].indexOf(".") == -1) { + strs[0] = location+"."+strs[0]; + } + if (strs[0].indexOf("Scaffold") == -1) { + strs[0] += "Scaffold"; + } + } else { + System.err.println("Can't find com.generationjava.test.test.properties."); + } + */ + strs[0] = "com.generationjava.tools."+StringUtils.capitalise(strs[0])+"Tool"; + + CommandLineToolRunner cltr = new CommandLineToolRunner(); + cltr.runTool(ClassW.getClass(strs[0]), CollectionsW.getSubArray(strs,1)); + } + +} diff --git a/genjava/gj-tools/src/java/com/generationjava/tools/Tool.java b/genjava/gj-tools/src/java/com/generationjava/tools/Tool.java new file mode 100644 index 00000000..c3d2eeb1 --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/tools/Tool.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.tools; + +import org.apache.commons.cli.CommandLine; + +public interface Tool { + + public CommandLine getCArgs(String flags, String[] args); + + public void runTool(String[] args) throws ToolException; + +} diff --git a/genjava/gj-tools/src/java/com/generationjava/tools/ToolException.java b/genjava/gj-tools/src/java/com/generationjava/tools/ToolException.java new file mode 100644 index 00000000..63fb717d --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/tools/ToolException.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.tools; + +import org.apache.commons.lang.exception.NestableException; + +public class ToolException extends NestableException { + + public ToolException() { + super(); + } + + public ToolException(String msg) { + super(msg); + } + + public ToolException(Throwable t) { + super(t); + } + + public ToolException(String msg, Throwable t) { + super(msg,t); + } + +} diff --git a/genjava/gj-tools/src/java/com/generationjava/util/ClassFinder.java b/genjava/gj-tools/src/java/com/generationjava/util/ClassFinder.java new file mode 100644 index 00000000..019cc258 --- /dev/null +++ b/genjava/gj-tools/src/java/com/generationjava/util/ClassFinder.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.util; + +import java.io.File; +import java.io.IOException; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; +import java.util.Iterator; + +import org.apache.commons.collections.IteratorUtils; +import org.apache.commons.lang.StringUtils; +import com.generationjava.tools.AbstractTool; +import com.generationjava.tools.CommandLineToolRunner; + +import org.apache.commons.cli.CommandLine; + +/** + * Find a Class by name. That is, find the directory or jar it is in. + */ +public class ClassFinder extends AbstractTool { + + // add an argument to return all duplicate fqnames in jars + static public void main(String[] strs) { + CommandLineToolRunner cltr = new CommandLineToolRunner(); + cltr.runTool(ClassFinder.class, strs); + } + + public void runTool(String[] strs) { + CommandLine cargs = getCArgs("fc:", strs); + ClassFinder cf = new ClassFinder(); + + if(cargs.hasOption("c")) { + cf.setClasspath((String)cargs.getOptionValue("c")); + } + + boolean fail = cargs.hasOption("f"); + + for(int i=0;i + + ../project.xml + gj-xml + GenJava-XML + 1.0 + 2002 + + + XML parser component of GenJava-Core. + + + XML Parser + + + + junit + 3.7 + + + + + diff --git a/genjava/gj-xml/src/java/com/generationjava/io/xml/XMLNode.java b/genjava/gj-xml/src/java/com/generationjava/io/xml/XMLNode.java new file mode 100644 index 00000000..72e59be3 --- /dev/null +++ b/genjava/gj-xml/src/java/com/generationjava/io/xml/XMLNode.java @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.io.xml; + +import java.util.Hashtable; +import java.util.Enumeration; +import java.util.Vector; + +/** + * An xml tag. It can be a processing instructon, an empty tag or + * a normal tag. Currently, if the tag is inside a namespace then + * that is a part of the name. That is, all names of tags are + * fully qualified by the namespace. + */ +public class XMLNode { + + static private Enumeration EMPTY = new NullEnumeration(); + + private Hashtable myAttrs; + private Hashtable myNodes; // allows quick lookup + private Vector myNodeList; // maintains order of myNodes + private String name; + private String value; + private boolean pi; + private boolean comment; + private boolean doctype; + + /** + * Empty Constructor. + */ + public XMLNode() { + this(""); + } + + /** + * Create a new node with this name. + */ + public XMLNode(String name) { + this.name = name; + } + + /** + * Add a child node to this node. + */ + public void addNode(XMLNode node) { + if(this.myNodes == null) { + this.myNodes = new Hashtable(); + this.myNodeList = new Vector(); + } + this.myNodeList.add(node); + Object obj = this.myNodes.get( node.getName() ); + if(obj == null) { + this.myNodes.put( node.getName(), node ); + } else + if(obj instanceof XMLNode) { + Vector vec = new Vector(); + vec.addElement(obj); + vec.addElement(node); + this.myNodes.put( node.getName(), vec ); + } else + if(obj instanceof Vector) { + Vector vec = (Vector)obj; + vec.addElement(node); + } + } + + // Enumerates a child node. Possibly needs renaming. + // That is, it enumerates a child nodes value. + /** + * + */ + public Enumeration enumerateNode(String name) { + if(this.myNodes == null) { + return EMPTY; + } + Object obj = this.myNodes.get( name ); + if(obj == null) { + return EMPTY; + } else + if(obj instanceof Vector) { + return ((Vector)obj).elements(); + } else { + return EMPTY; + } + } + + /** + * Add an attribute with specified name and value. + */ + public void addAttr(String name, String value) { + if(this.myAttrs == null) { + this.myAttrs = new Hashtable(); + } + this.myAttrs.put( name, value ); + } + + /** + * Get the attribute with the specified name. + */ + public String getAttr(String name) { + if(myAttrs == null) { + return null; + } + return (String)this.myAttrs.get(name); + } + + /** + * Enumerate over all the attributes of this node. + * In the order they were added. + */ + public Enumeration enumerateAttr() { + if(this.myAttrs == null) { + return EMPTY; + } else { + return this.myAttrs.keys(); + } + } + + /** + * Get the node with the specified name. + */ + public XMLNode getNode(String name) { + if(this.myNodes == null) { + return null; + } + Object obj = this.myNodes.get(name); + if(obj instanceof XMLNode) { + return (XMLNode)obj; + } + return null; + } + + /** + * Enumerate over all of this node's children nodes. + */ + public Enumeration enumerateNode() { + if(this.myNodes == null) { + return EMPTY; + } else { +// return this.myNodes.elements(); + return this.myNodeList.elements(); + } + } + + /** + * Get the name of this node. Includes the namespace. + */ + public String getName() { + return this.name; + } + + /** + * Get the namespace of this node. + */ + public String getNamespace() { + if(this.name.indexOf(":") != -1) { + return this.name.substring(0,this.name.indexOf(":")); + } else { + return ""; + } + } + + /** + * Get the tag name of this node. Doesn't include namespace. + */ + public String getTagName() { + if(this.name.indexOf(":") != -1) { + return this.name.substring(this.name.indexOf(":")+1); + } else { + return this.name; + } + } + + /** + * Get the appended toString's of the children of this node. + * For a text node, it will print out the plaintext. + */ + public String getValue() { + if(isComment()) { + return ""; + } + if(isDocType()) { + return ""; + } + if(this.value != null) { + return this.value; + } + if(isInvisible()) { + return ""; + } + // QUERY: shouldnt call toString. Needs to improve + if(this.myNodeList != null) { + StringBuffer buffer = new StringBuffer(); + Enumeration enum = enumerateNode(); + while(enum.hasMoreElements()) { + buffer.append(enum.nextElement().toString()); + } + return buffer.toString(); + } + return null; + } + + /** + * Set the plaintext contained in this node. + */ + public void setPlaintext(String str) { + this.value = str; + } + + /** + * Is this a normal tag? + * That is, not plaintext, not comment and not a pi. + */ + public boolean isTag() { + return !(this.pi || (this.name == null) || (this.value != null)); + } + + /** + * Is it invisible + */ + public boolean isInvisible() { + return this.name == null; + } + + /** + * Set whether this node is invisible or not. + */ + public void setInvisible(boolean b) { + if(b) { + this.name = null; + } + } + + /** + * Is it a doctype + */ + public boolean isDocType() { + return this.doctype; + } + + /** + * Set whether this node is a doctype or not. + */ + public void setDocType(boolean b) { + this.doctype = b; + } + + /** + * Is it a comment + */ + public boolean isComment() { + return this.comment; + } + + /** + * Set whether this node is a comment or not. + */ + public void setComment(boolean b) { + this.comment = b; + } + + /** + * Is it a processing instruction + */ + public boolean isPI() { + return this.pi; + } + + /** + * Set whether this node is a processing instruction or not. + */ + public void setPI(boolean b) { + this.pi = b; + } + + // IMPL: Assumes that you're unable to remove nodes from + // a parent node. removeNode and removeAttr is likely to + // become a needed functionality. + /** + * Is this node empty. + */ + public boolean isEmpty() { + return (this.myNodes == null); + } + + /** + * Is this a text node. + */ + public boolean isTextNode() { + return ((this.value != null) && !comment && !doctype && !pi); + } + + // not entirely necessary, but allows XMLNode's to be output + // int XML by calling .toString() on the root node. + // Probably wants some indentation handling? + /** + * Turn this node into a String. Outputs the node as + * XML. So a large amount of output. + */ + public String toString() { + if(isComment()) { + return ""; + } + if(isDocType()) { + return ""; + } + if(value != null) { + return value; + } + + StringBuffer tmp = new StringBuffer(); + + if(!isInvisible()) { + tmp.append("<"); + if(isPI()) { + tmp.append("?"); + } + tmp.append(name); + } + + Enumeration enum = enumerateAttr(); + while(enum.hasMoreElements()) { + tmp.append(" "); + String obj = (String)enum.nextElement(); + tmp.append(obj); + tmp.append("=\""); + tmp.append(getAttr(obj)); + tmp.append("\""); + } + if(isEmpty()) { + if(isPI()) { + tmp.append("?>"); + } else { + if(!isInvisible()) { + tmp.append("/>"); + } + } + } else { + if(!isInvisible()) { + tmp.append(">"); + } + + tmp.append(bodyToString()); + + if(!isInvisible()) { + tmp.append("\n"); + } + } + return tmp.toString(); + } + + /** + * Get the String version of the body of this tag. + */ + public String bodyToString() { + StringBuffer tmp = new StringBuffer(); + Enumeration enum = enumerateNode(); + while(enum.hasMoreElements()) { + Object obj = enum.nextElement(); + if(obj instanceof XMLNode) { + XMLNode node = (XMLNode)obj; + tmp.append(node); + } else + if(obj instanceof Vector) { + Vector nodelist = (Vector)obj; + Enumeration nodeEnum = nodelist.elements(); + while(nodeEnum.hasMoreElements()) { + XMLNode node = (XMLNode)nodeEnum.nextElement(); + tmp.append(node); + } + } + } + return tmp.toString(); + } + +} + +class NullEnumeration implements Enumeration { + public Object nextElement() { + return null; + } + + public boolean hasMoreElements() { + return false; + } +} diff --git a/genjava/gj-xml/src/java/com/generationjava/io/xml/XMLParser.java b/genjava/gj-xml/src/java/com/generationjava/io/xml/XMLParser.java new file mode 100644 index 00000000..0e6d81e2 --- /dev/null +++ b/genjava/gj-xml/src/java/com/generationjava/io/xml/XMLParser.java @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.generationjava.io.xml; + +import java.io.Reader; +import java.io.IOException; +import java.util.Stack; + +/** + * A tiny parser of xml text. It is intended to deal with simple + * config files. + */ +public class XMLParser { + + // various states in which the parser may be. + static final private int VACUUM = 1; + static final private int IN_TAG = 2; + static final private int IN_TAG_NAME = 3; + static final private int CLOSING_TAG = 9; + static final private int SLASH = 4; + static final private int ATTR_NAME = 5; + static final private int END_ATTR_NAME = 6; + static final private int ATTR_VALUE = 7; + static final private int END_ATTR_VALUE = 8; + static final private int START_COMMENT = 10; + static final private int IN_COMMENT = 11; + // special state to handle the DOCTYPE 'tag' + static final private int IN_DOCTYPE = 12; + static final private int IN_DTD = 13; + + public XMLParser() { + } + + /** + * Parse an XML text read in from a Reader. + * Returns the root node of the xml text. + */ + public XMLNode parseXML(Reader reader) throws IOException { + int state = VACUUM; + int x = 1; // current character number + int y = 1; // current line number + int rch = 0; + char ch; + boolean pi = false; + + StringBuffer tag_name = new StringBuffer(); + StringBuffer attr_name = new StringBuffer(); + StringBuffer attr_value = new StringBuffer(); + StringBuffer value = new StringBuffer(); + + XMLNode root = null; + XMLNode node = null; + + + // the current parent. + XMLNode parent = null; + + // Stack is used to remember the hierarchy of parents. + Stack stack = new Stack(); + + while( (rch = reader.read()) != -1) { + ch = (char)rch; + // QUERY: Should newlines only be allowed in a VACUUM ? + // error messaging + x++; + if(ch == '\n') { + y++; + x = 1; + continue; + } + + switch(state) { + case VACUUM: { + if(ch == '<') { + pi = false; + state = IN_TAG_NAME; + if( value.length() != 0 ) { + node = new XMLNode(tag_name.toString()); + node.setPlaintext(value.toString().trim()); + parent.addNode(node); + value.setLength(0); + } + } else + if( (ch == ' ') || (ch == '\t') ) { + if(value.length() != 0) { + value.append(ch); + } + continue; + } else + if(ch == '\r') { // part of a newline. + if(value.length() != 0) { + value.append(ch); + } + continue; + } else { + value.append(ch); + } + } + break; + + case START_COMMENT: { + if(ch == '-') { + // feels bad to do this here. + ch = (char)reader.read(); + if(ch == '-') { + state = IN_COMMENT; + } else { + value.append("!-"); + value.append(ch); + } + } else { + tag_name.append('!'); + tag_name.append(ch); + state = IN_TAG_NAME; + } + } + break; + + case IN_COMMENT: { + if(ch == '-') { + // feels bad to do this here. + ch = (char)reader.read(); + if(ch == '-') { + ch = (char)reader.read(); + if(ch == '>') { + node = new XMLNode(); + node.setPlaintext(value.toString().trim()); + node.setComment(true); + if(parent == null) { + parent = new XMLNode(); + parent.setInvisible(true); + root = parent; + } + parent.addNode(node); + value.setLength(0); + state = VACUUM; + } else { + value.append("--"); + value.append(ch); + } + } else { + value.append("-"); + value.append(ch); + } + } else { + value.append(ch); + } + } + break; + + case IN_DOCTYPE: { + if(ch == '[') { + value.append(ch); + state = IN_DTD; + } else + if(ch == '>') { + node = new XMLNode("!DOCTYPE"); + node.setPlaintext(value.toString()); + node.setDocType(true); + if(parent == null) { + parent = new XMLNode(); + parent.setInvisible(true); + root = parent; + } + parent.addNode(node); + value.setLength(0); + state = VACUUM; + } else { + value.append(ch); + } + } + break; + + case IN_DTD: { + if(ch == ']') { + value.append(ch); + state = IN_DOCTYPE; + } else { + value.append(ch); + } + } + + case IN_TAG_NAME: { + if( (ch == '!') && (tag_name.length() == 0) ) { + state = START_COMMENT; + } else + if( !pi && (ch == '?') && (tag_name.length() == 0) ) { + pi = true; + } else + if( (ch == '/') && (tag_name.length() == 0) ) { + // closing tag + parent = (XMLNode)stack.pop(); + state = CLOSING_TAG; + } else + if( ((ch == ' ') || (ch == '\t') || (ch == '>') || (ch == '/')) || (ch == '?') ) { + if("!DOCTYPE".equals(tag_name.toString())) { + state = IN_DOCTYPE; + tag_name.setLength(0); + continue; + } + if(pi) { + if(parent == null) { + parent = new XMLNode(); + parent.setInvisible(true); + root = parent; + } + } + node = new XMLNode(tag_name.toString()); + node.setPI(pi); + pi = false; + if(root == null) { + root = node; + } + if(parent != null) { + parent.addNode(node); + } + tag_name.setLength(0); + if( (ch == '/') || (ch == '?') ) { + state = SLASH; + } else + if(ch == '>') { + state = VACUUM; + stack.push(parent); + parent = node; + } else { + state = IN_TAG; + } + } else { + tag_name.append(ch); + } + } + break; + + case IN_TAG: { + if((ch == ' ') || (ch == '\t') ) { + continue; + } else + if(ch == '>') { + state = VACUUM; + stack.push(parent); + parent = node; + } else + if( (ch == '/') || (ch == '?') ) { + // empty tag + state = SLASH; + } else { + state = ATTR_NAME; + attr_name.setLength(1); + attr_name.setCharAt(0,ch); + } + } + break; + + case SLASH: { + if(ch == '>') { + state = VACUUM; + } else { + state = IN_TAG; + } + } + break; + + case CLOSING_TAG: { + if(ch == '>') { + state = VACUUM; + } else { + continue; + } + } + break; + + case ATTR_NAME: { + if((ch == ' ') || (ch == '\t') ) { + node.addAttr(attr_name.toString(), attr_name.toString()); + state = IN_TAG; + } else + if(ch == '=') { + state = END_ATTR_NAME; + } else { + attr_name.append(ch); + } + } + break; + + case END_ATTR_NAME: { + if(ch == '"') { + state = ATTR_VALUE; + attr_value.setLength(0); + } else { + state = ATTR_NAME; + } + } + break; + + case ATTR_VALUE: { + if(ch == '"') { + node.addAttr(attr_name.toString(), attr_value.toString()); + state = IN_TAG; + } else { + attr_value.append(ch); + } + } + break; + } + } + return root; + } + +} diff --git a/genjava/gj-xml/src/java/com/generationjava/util/XmlProperties.java b/genjava/gj-xml/src/java/com/generationjava/util/XmlProperties.java new file mode 100644 index 00000000..8ec64751 --- /dev/null +++ b/genjava/gj-xml/src/java/com/generationjava/util/XmlProperties.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Genjava-Core nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +// XmlProperties.java +package com.generationjava.util; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.util.Properties; +import java.util.Enumeration; + +import com.generationjava.io.xml.XMLParser; +import com.generationjava.io.xml.XMLNode; + +/** + */ +public class XmlProperties extends Properties { + + static public XmlProperties load(File file) { + XmlProperties props = new XmlProperties(); + return props; + } + + public XmlProperties() { + super(); + } + + public XmlProperties(Properties props) { + super(props); + } + + public void load(InputStream in) throws IOException { + InputStreamReader reader = new InputStreamReader(in); + this.load( reader ); + reader.close(); + } + + public void load(Reader reader) throws IOException { + XMLParser parser = new XMLParser(); + XMLNode root = parser.parseXML(reader); + Enumeration enum = root.enumerateNode(); + while(enum.hasMoreElements()) { + XMLNode node = (XMLNode)enum.nextElement(); + add("", node); + } + } + + public void add(String level, XMLNode node) { + if( node.getValue() != null ) { + setProperty( level+node.getName(), node.getValue()); + } + Enumeration attrs = node.enumerateAttr(); + if(attrs != null) { + while(attrs.hasMoreElements()) { + String attr = (String)attrs.nextElement(); + setProperty( level+node.getName()+"."+attr, node.getAttr(attr)); + } + } + Enumeration nodes = node.enumerateNode(); + if(nodes != null) { + while(nodes.hasMoreElements()) { + XMLNode subnode = (XMLNode)nodes.nextElement(); + add(level+subnode.getName()+".", subnode); + } + } + } + + public Object setProperty(String key, String value) { + return put( key, value ); + } + + // has to make sure not to write out any defaults + public void save(OutputStream outstrm, String header) { + super.save(outstrm,header); + } + // has to make sure not to write out any defaults + public void store(OutputStream outstrm, String header) throws IOException { + super.store(outstrm,header); + } +} diff --git a/genjava/project.properties b/genjava/project.properties new file mode 100644 index 00000000..56a44b4c --- /dev/null +++ b/genjava/project.properties @@ -0,0 +1,11 @@ +maven.repo.remote=http://www.osjava.org/maven/,http://www.ibiblio.org/maven/ + +maven.ui.navcol.background=#f4f8d8 +maven.ui.banner.background=#000066 +maven.ui.section.background=#000066 +maven.ui.subsection.background=#000066 +maven.xdoc.date = left +maven.xdoc.version = v${pom.currentVersion} +maven.ui.breadcrumbs.background=#f4f8d8 + +maven.xdoc.poweredby.image=maven-feather.png diff --git a/genjava/project.xml b/genjava/project.xml new file mode 100644 index 00000000..52f5296f --- /dev/null +++ b/genjava/project.xml @@ -0,0 +1,81 @@ + + + + 3 + genjava + GenJava Master Maven POM + 1.0 + + + OSJava + http://www.osjava.org/ + /images/osjava.gif + + 2000 + com.generationjava + /images/1x1.gif + + http://www.osjava.org/genjava-core/${pom.id}/ + http://www.osjava.org:8080/jira/secure/BrowseProject.jspa?id=10010 + www.osjava.org/genjava-core + /sites/org/osjava/www/releases/official/genjava-core/${pom.id}/ + /sites/org/osjava/www/releases/official/genjava-core/${pom.id}/ + + + + + + osjava-users + http://lists.flamefew.net/mailman/listinfo/osjava-users + http://lists.flamefew.net/mailman/listinfo/osjava-users + http://lists.flamefew.net/mailman/private/osjava-users/ + + + + + + Henri Yandell + hen + bayard@generationjava.com + GenerationJava + + Java Developer + + + + + + + + Steve Heath + steve@smallcogs.com + + + + + bayard@www.generationjava.com + src/java + src/test + + + + + **/*Test.java + + + + + + **/*.properties + + + + + + + diff --git a/genjava/xdocs/navigation.xml b/genjava/xdocs/navigation.xml new file mode 100644 index 00000000..d2e38e4b --- /dev/null +++ b/genjava/xdocs/navigation.xml @@ -0,0 +1,15 @@ + + + + genjava-core + + + + + + + + + + + diff --git a/hibernate-taglib/META-INF/taglib.tld b/hibernate-taglib/META-INF/taglib.tld new file mode 100644 index 00000000..e8e4ce65 --- /dev/null +++ b/hibernate-taglib/META-INF/taglib.tld @@ -0,0 +1,36 @@ + + + + + + 1.0 + 1.1 + hibernate + http://www.osjava.org/taglibs/hibernate-1.0 + Hibernate in a taglib. + + find + org.osjava.hibernate.taglib.FindTag + JSP + + var + true + true + + + + param + org.osjava.hibernate.taglib.ParamTag + JSP + + value + false + true + + + type + true + true + + + diff --git a/hibernate-taglib/org/osjava/hibernate/taglib/FindTag.java b/hibernate-taglib/org/osjava/hibernate/taglib/FindTag.java new file mode 100644 index 00000000..847d07e4 --- /dev/null +++ b/hibernate-taglib/org/osjava/hibernate/taglib/FindTag.java @@ -0,0 +1,129 @@ +package org.osjava.hibernate.taglib; + +import java.io.IOException; +import java.io.StringWriter; + +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.BodyTagSupport; + +import net.sf.hibernate.SessionFactory; +import net.sf.hibernate.Session; +import net.sf.hibernate.cfg.Configuration; +import net.sf.hibernate.HibernateException; +import net.sf.hibernate.Hibernate; +import net.sf.hibernate.type.Type; + +// Make this need a DataSource +public class FindTag extends BodyTagSupport { + + private String var; + private String expected; + + private List types = new ArrayList(); + private List parameters = new ArrayList(); + + public FindTag() { + } + + public String getVar() { return this.var; } + public void setVar(String var) { this.var = var; } + + public String getExpected() { return this.expected; } + public void setExpected(String expected) { this.expected = expected; } + +// move to doStart? + public int doEndTag() throws JspException { + if(bodyContent == null) { + return EVAL_PAGE; + } + + String query = JspUtils.getBody(bodyContent); + System.out.println("QUERY: "+query); + Session hSession = null; + try { + SessionFactory hSf = new Configuration().configure().buildSessionFactory(); + hSession = hSf.openSession(); + List categories = null; + if(this.types.size() == 0 && + this.parameters.size() == 0) + { + categories = hSession.find(query); + } else { + categories = hSession.find( + query, + convertToHibernateValueArray(this.parameters, this.types), + convertToHibernateArray(this.types) + ); + } + if("one".equals(expected)) { + if(categories.size() == 1) { + pageContext.setAttribute(this.var, categories.get(1)); + } else { + throw new JspTagException("Only one value was expected. "); + } + } else { + pageContext.setAttribute(this.var, categories); + } + } catch(HibernateException he) { + he.printStackTrace(); + } finally { + this.types.clear(); + this.parameters.clear(); + if(hSession != null) { + try { + hSession.close(); + } catch(HibernateException he) { + // ignore + } + } + } + + return EVAL_PAGE; + } + + // convert a list of hibernate strings to the parameters... + // bit lame, but it works... + // I think this will become a String-based API to Hibernate + private Type[] convertToHibernateArray(List types) { + ArrayList list2 = new ArrayList(); + Iterator itr = types.iterator(); + while(itr.hasNext()) { + String parameter = itr.next().toString(); + if("Hibernate.LONG".equals(parameter)) { + list2.add(Hibernate.LONG); + } + } + System.err.println("L2: "+list2); + return (Type[]) list2.toArray(new Type[0]); + } + + private Object[] convertToHibernateValueArray(List values, List types) { + ArrayList list2 = new ArrayList(); + for(int i=0; i + + + 3 + oscube + oscube + 0.1 + + OSJava + http://www.osjava.org/ + http://www.osjava.org/images/osjava.gif + + 2003 + org.osjava.oscube + http://www.osjava.org/images/1x1.gif + + + A container engine. + + + A container engine + + http://www.osjava.org/oscube/ + http://www.osjava.org:8080/jira/secure/BrowseProject.jspa?id=10021 + www.generationjava.com/maven/oscube + /sites/org/osjava/www/maven/oscube/ + /sites/org/osjava/www/releases/official/ + + + scm:cvs:pserver:anonymous@cvs.osjava.org:/var/cvs:oscube + http://www.osjava.org/view-cvs/viewcvs.cgi/oscube/ + + + + + osjava-users + http://lists.flamefew.net/mailman/listinfo/osjava-users + http://lists.flamefew.net/mailman/listinfo/osjava-users + http://lists.flamefew.net/mailman/private/osjava-users/ + + + + + + + Henri Yandell + hen + bayard@generationjava.com + GenerationJava + + Java Developer + + + + + + + + + log4j + 1.2.7 + http://jakarta.apache.org/log4j/ + + + commons-lang + 1.0 + http://jakarta.apache.org/commons/lang.html + + + commons-collections + 2.1 + http://jakarta.apache.org/commons/ + + + commons-dbutils + SNAPSHOT + http://jakarta.apache.org/commons/ + + + genjava + gj-core + 3.0 + http://www.generationjava.com/ + + + simple-jndi + 0.7 + http://www.generationjava.com/ + + + quartz + 1.0.7 + http://www.part.net/quartz.html + + + + + + bayard@www.generationjava.com + + src/java + + + + + + maven-jxr-plugin + maven-javadoc-plugin + maven-license-plugin + maven-changes-plugin + maven-statcvs-plugin + maven-changelog-plugin + + + diff --git a/oscube/src/java/org/osjava/oscube/container/AbstractConfig.java b/oscube/src/java/org/osjava/oscube/container/AbstractConfig.java new file mode 100644 index 00000000..546fcda0 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/container/AbstractConfig.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scraping-Engine nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.container; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang.NumberUtils; +import java.util.Date; + +public abstract class AbstractConfig implements Config { + + private String context = ""; + + protected abstract Object getValue(String key); + + public Object get(String key) { + return getValue( getContext()+key ); + } + + public boolean has(String key) { + return (get(key) != null); + } + + public Object getAbsolute(String key) { + return getValue(key); + } + + public String getString(String key) { + return (String)get(key); + } + + public Date getDate(String key) { + try { + return java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT).parse(key); + } catch(java.text.ParseException pe) { + return null; + } + } + + // rely on simple-jndi's type + public int getInt(String key) { + return NumberUtils.stringToInt(getString(key)); + } + + public List getList(String key) { + Object obj = get(key); + if(!(obj instanceof List)) { + List list = new ArrayList(1); + list.add(obj); + obj = list; + } + return (List)obj; + } + + public void setContext(String context) { + this.context = context; + } + + public String getContext() { + return this.context; + } + + public Config cloneConfig() { + try { + return (Config)this.clone(); + } catch(CloneNotSupportedException cnse) { + // ignore + throw new RuntimeException("Cloning of a Config failed. This should be impossible. "); + } + } + +} diff --git a/oscube/src/java/org/osjava/oscube/container/Config.java b/oscube/src/java/org/osjava/oscube/container/Config.java new file mode 100644 index 00000000..ae393df2 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/container/Config.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.container; + +import java.util.List; +import java.util.Date; + +public interface Config extends Cloneable { + + public Object get(String key); + public boolean has(String key); + public Object getAbsolute(String key); + public String getString(String key); + public int getInt(String key); + public Date getDate(String key); + public List getList(String key); + public void setContext(String context); + public String getContext(); + public Config cloneConfig(); + +} diff --git a/oscube/src/java/org/osjava/oscube/container/ConfigFactory.java b/oscube/src/java/org/osjava/oscube/container/ConfigFactory.java new file mode 100644 index 00000000..8461690c --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/container/ConfigFactory.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.container; + +public class ConfigFactory { + + static public Config getConfig(String[] args) { + return new JndiConfig(); + } + +} diff --git a/oscube/src/java/org/osjava/oscube/container/Engine.java b/oscube/src/java/org/osjava/oscube/container/Engine.java new file mode 100644 index 00000000..2c8b93d5 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/container/Engine.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.container; + +import java.util.List; +import java.io.Reader; + +public class Engine { + + public static void main(String[] args) throws Exception { + Engine engine = new Engine(); + // load the config + Config cfg = ConfigFactory.getConfig(args); + String runStr = cfg.getString("org.osjava.oscube.runner"); + Class cl = Class.forName(runStr); + Runner runner = (Runner) cl.newInstance(); + engine.run(runner, args); + } + +/// TODO: Implement the Scheduler aspect +/// The Scheduler notifies only this class. It is +/// then up to this Engine to run the parsers. +/// TODO: Put the oscube.container and db in a different thread + public void run(Runner runner, String[] args) { + // load the config + Config cfg = ConfigFactory.getConfig(args); + + // get the prefix for this instance, this is the active + // object which will be run by the runner + String prefix = cfg.getString("org.osjava.oscube.prefix"); + + // test and how schedule=startup will be handled + List list = cfg.getList(prefix); + for(int i=0; i. + public Iterator iterateRows() { + // use a better class later + ArrayList list = new ArrayList(1); + Object[] objs = new Object[] { obj }; + list.add(objs); + return list.iterator(); + } + +} diff --git a/oscube/src/java/org/osjava/oscube/container/TabularResult.java b/oscube/src/java/org/osjava/oscube/container/TabularResult.java new file mode 100644 index 00000000..e07a6fbf --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/container/TabularResult.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.container; + +import java.util.Iterator; + +public class TabularResult implements Result { + + private Iterator iterator; + + public TabularResult(Iterator iterator) { + this.iterator = iterator; + } + + // returns Iterator of . + // very simple system to start with + // so our JdbcStore can be simple + public Iterator iterateRows() { + return this.iterator; + } + +} diff --git a/oscube/src/java/org/osjava/oscube/service/notify/NotificationException.java b/oscube/src/java/org/osjava/oscube/service/notify/NotificationException.java new file mode 100644 index 00000000..14b9ac0a --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/notify/NotificationException.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.notify; + +public class NotificationException extends org.apache.commons.lang.exception.NestableException { + + public NotificationException(String msg) { + super(msg); + } + + public NotificationException(String msg, Throwable t) { + super(msg, t); + } +} diff --git a/oscube/src/java/org/osjava/oscube/service/notify/NotificationFactory.java b/oscube/src/java/org/osjava/oscube/service/notify/NotificationFactory.java new file mode 100644 index 00000000..005ad022 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/notify/NotificationFactory.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.notify; + +import org.osjava.oscube.util.FactoryUtils; +import org.osjava.oscube.container.Session; +import org.osjava.oscube.container.Config; + +public class NotificationFactory { + + static public Notifier getSuccessNotifier(Config cfg, Session session) { + String name = cfg.getString("notifier.success"); + Notifier notifier = (Notifier)FactoryUtils.getObject(name, "Notifier", "org.osjava.oscube.service.notify"); + if(notifier == null) { + throw new RuntimeException("Unable to find Success Notifier. "); + } + return notifier; + } + + static public Notifier getErrorNotifier(Config cfg, Session session, Exception e) { + String name = cfg.getString("notifier.error."+e.getClass().getName()); + if(name == null) { + name = cfg.getString("notifier.error"); + } + Notifier notifier = (Notifier)FactoryUtils.getObject(name, "Notifier", "org.osjava.oscube.service.notify"); + if(notifier == null) { + throw new RuntimeException("Unable to find Error Notifier. "); + } + return notifier; + } + +} diff --git a/oscube/src/java/org/osjava/oscube/service/notify/Notifier.java b/oscube/src/java/org/osjava/oscube/service/notify/Notifier.java new file mode 100644 index 00000000..00ccafa8 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/notify/Notifier.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.notify; + +import org.osjava.oscube.container.Session; +import org.osjava.oscube.container.Config; + +// can notify success and error. How to separate? +// have a Formatter for formatting the thing? Opposite of a +// Converter really + +public interface Notifier { + + public void notify(Config cfg, Session session) throws NotificationException; + +} diff --git a/oscube/src/java/org/osjava/oscube/service/notify/NullNotifier.java b/oscube/src/java/org/osjava/oscube/service/notify/NullNotifier.java new file mode 100644 index 00000000..8329798a --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/notify/NullNotifier.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.notify; + +import org.osjava.oscube.container.Config; +import org.osjava.oscube.container.Session; + +// so currently it's doing the job of a default notifier +public class NullNotifier implements Notifier { + + public void notify(Config cfg, Session session) { + Exception error = (Exception)session.get(cfg.getContext()+".error"); + if(error != null) { + error.printStackTrace(); + } + } + +} diff --git a/oscube/src/java/org/osjava/oscube/service/store/FileStore.java b/oscube/src/java/org/osjava/oscube/service/store/FileStore.java new file mode 100644 index 00000000..b22d3987 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/store/FileStore.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.store; + +import java.util.Iterator; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.net.URL; + +import com.generationjava.io.StreamW; + +import org.apache.log4j.Logger; + +import org.osjava.oscube.container.Config; +import org.osjava.oscube.container.Session; +import org.osjava.oscube.container.Header; +import org.osjava.oscube.container.Result; + +public class FileStore implements Store { + + private static Logger logger = Logger.getLogger(FileStore.class); + +// FileStore assumes that the result contains a URL, InputStream, other? +// Assumes only row(?) +// TODO: If no saveAs, then it can handle multiple rows +// TODO: Optional argument 'maintainExtension=true'. In which case the +// saveAs does not need to mention the extension. + public void store(Result result, Config cfg, Session session) throws StoringException { + OutputStream out = null; + InputStream in = null; +try { + String path = cfg.getString("file.path"); + String saveAs = cfg.getString("file.saveAs"); + + File file = new File(path, saveAs); + FileOutputStream fos = new FileOutputStream(file); + + Iterator iterator = result.iterateRows(); + if(iterator.hasNext()) { + Object[] row = (Object[])iterator.next(); + if(row.length == 0) { + logger.error("Empty row found. Skipping. "); + return; + } + in = open(row[0]); + if(in != null) { + StreamW.pushStream(in, fos); + } + } + +} catch(IOException ioe) { + throw new StoringException("File I/O Storing Error: "+ioe.getMessage(), ioe); +} finally { + try { if(in != null) in.close(); } catch(IOException ioe) { } + try { if(out != null) out.close(); } catch(IOException ioe) { } +} + } + + public boolean exists(Header header, Config cfg, Session session) throws StoringException { + // need to write some kind of checking in here + return false; + } + + private InputStream open(Object obj) throws IOException { + if(obj instanceof URL) { + URL url = (URL) obj; + return url.openStream(); + } else + if(obj instanceof String) { + return new java.io.ByteArrayInputStream( ( (String) obj ).getBytes() ); + } else + if(obj instanceof InputStream) { + return (InputStream) obj; + } else + if(obj instanceof File) { + return new java.io.FileInputStream( (File) obj); + } else + if(obj instanceof byte[]) { + return new java.io.ByteArrayInputStream( (byte[]) obj); + } else { + return null; + } + } +} diff --git a/oscube/src/java/org/osjava/oscube/service/store/JdbcStore.java b/oscube/src/java/org/osjava/oscube/service/store/JdbcStore.java new file mode 100644 index 00000000..26ac10e9 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/store/JdbcStore.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.store; + +import java.util.Iterator; +import javax.sql.DataSource; +import java.sql.*; +import org.apache.commons.dbutils.DbUtils; +import org.apache.commons.lang.StringUtils; + +import org.apache.log4j.Logger; + +import org.osjava.oscube.container.Config; +import org.osjava.oscube.container.Session; +import org.osjava.oscube.container.Header; +import org.osjava.oscube.container.Result; + +public class JdbcStore implements Store { + + private static Logger logger = Logger.getLogger(JdbcStore.class); + + public void store(Result result, Config cfg, Session session) throws StoringException { + Connection conn = null; +try { + // get DataSource from cfg + String dsname = cfg.getString("jdbc.DS"); +// System.err.println("DSNAME: "+dsname); +// System.err.println("/DSNAME: "+cfg.getAbsolute(dsname)); + DataSource ds = (DataSource)cfg.getAbsolute(dsname); +// System.err.println("DataSource: "+ds); + conn = ds.getConnection(); +// System.err.println("CONN: "+conn); + String sql = cfg.getString("jdbc.sql"); +// System.err.println("SQL: "+sql); + String table = cfg.getString("jdbc.table"); +// System.err.println("Table: "+table); + if(sql == null) { + if(table == null) { + throw new StoringException(cfg.getContext()+".jdbc.sql or "+cfg.getContext()+".jdbc.table must be specified. "); + } + } + + Iterator iterator = result.iterateRows(); + while(iterator.hasNext()) { + Object[] row = (Object[])iterator.next(); + if(row.length == 0) { + logger.error("Empty row found. Skipping. "); + continue; + } + if(sql == null) { + if(table != null) { + sql = "INSERT INTO " + table + " VALUES(?"+ StringUtils.repeat(", ?", row.length-1) + ")"; + } + } + int count = DbUtils.executeUpdate( conn, sql, row ); + } + +} catch(SQLException sqle) { + throw new StoringException("JDBC Storing Error: "+sqle.getMessage(), sqle); +} finally { + DbUtils.closeQuietly( conn ); +} + } + + public boolean exists(Header header, Config cfg, Session session) throws StoringException { + // need to write some kind of checking in here + return false; + } +} diff --git a/oscube/src/java/org/osjava/oscube/service/store/NullStore.java b/oscube/src/java/org/osjava/oscube/service/store/NullStore.java new file mode 100644 index 00000000..df3ee651 --- /dev/null +++ b/oscube/src/java/org/osjava/oscube/service/store/NullStore.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003, Henri Yandell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * + Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + Neither the name of Scabies nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.osjava.oscube.service.store; + +import java.util.Iterator; + +import org.osjava.oscube.container.Config; +import org.osjava.oscube.container.Session; +import org.osjava.oscube.container.Header; +import org.osjava.oscube.container.Result; + +public class NullStore implements Store { + + public void store(Result result, Config cfg, Session session) throws StoringException { + if(false) throw new StoringException(null,null); + Iterator iterator = result.iterateRows(); + int i=0; + while(iterator.hasNext()) { + Object[] array = (Object[])iterator.next(); + for(int j=0; j +interpolate.properties diff --git a/pergamum/Style.java b/pergamum/Style.java new file mode 100644 index 00000000..55bce875 --- /dev/null +++ b/pergamum/Style.java @@ -0,0 +1,41 @@ +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.SAXException; +import org.w3c.dom.*; + +public class Style { + + public static void main(String[] args) { + try { + run(args); + } catch(Throwable t) { + t.printStackTrace(); + } + } + public static void run(String[] args) throws TransformerException, TransformerConfigurationException, FileNotFoundException, IOException, ParserConfigurationException, SAXException { + if(args.length != 2) { + throw new IllegalArgumentException("Must be 2 arguments, book xml and page xsl "); + } + + // Generate the book pages + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = tFactory.newTransformer(new StreamSource(args[1])); + // Use this in filename + String name = "docs/"+args[0].substring(0, args[0].length()-4)+".html"; + + transformer.transform(new StreamSource(args[0]), new StreamResult(new FileOutputStream(name))); + System.out.println(". "+name); + } +} diff --git a/pergamum/db/books.xml b/pergamum/db/books.xml new file mode 100644 index 00000000..5cd66e94 --- /dev/null +++ b/pergamum/db/books.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pergamum/db/publishers.xml b/pergamum/db/publishers.xml new file mode 100644 index 00000000..57100ffc --- /dev/null +++ b/pergamum/db/publishers.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/pergamum/docs/books.html b/pergamum/docs/books.html new file mode 100644 index 00000000..2ee47d30 --- /dev/null +++ b/pergamum/docs/books.html @@ -0,0 +1,406 @@ + + + +Open Source Java Books + + +

Open Source Java Books

+ +

Apache Struts

+ + +

Apache Jakarta Tapestry

+ + +

Apache Ant

+ + +

Apache Jakarta General

+ + +

Apache Jakarta Commons

+ + +

Apache Jakarta Tomcat

+ + +

JUnit

+ + +

XDoclet

+ + +

General

+ + +

Eclipse

+ + +

Hibernate

+ + +

JBoss

+ + + + diff --git a/pergamum/page.xsl b/pergamum/page.xsl new file mode 100644 index 00000000..073c334a --- /dev/null +++ b/pergamum/page.xsl @@ -0,0 +1,39 @@ + + + + + + + <xsl:value-of select="@name"/> + + +

+ + + +
+ + +

+
+
+ + + + + + + + + + + + + + +
  • +
    () - [amz] - [bkp]
  • +
    + +
    diff --git a/pergamum/plan.txt b/pergamum/plan.txt new file mode 100644 index 00000000..a790e3ab --- /dev/null +++ b/pergamum/plan.txt @@ -0,0 +1,10 @@ +Assemble ISBN's for books under category/sub-category +Pull these from an xml file: db.xml. + +This should then talk to Amazon's web service? To get the information +about those books, apply an xsl? and create a series of html files. + +Amazon's web service is bad. Enforces I link to them and only them. +So apply an xsl to an xml db. Add the names of the books later. + +XML -> XSL creates one page with diff --git a/pergamum/run.sh b/pergamum/run.sh new file mode 100755 index 00000000..40bee78d --- /dev/null +++ b/pergamum/run.sh @@ -0,0 +1 @@ +java Style books.xml page.xsl diff --git a/runsql/example/config/CmdLine.properties b/runsql/example/config/CmdLine.properties new file mode 100644 index 00000000..2bc4007a --- /dev/null +++ b/runsql/example/config/CmdLine.properties @@ -0,0 +1,5 @@ +com.generationjava.jndi.datasource=true +driver=org.hsqldb.jdbcDriver +url=jdbc:hsqldb:hsql://localhost +user=sa +password= diff --git a/runsql/example/jndi.properties b/runsql/example/jndi.properties new file mode 100644 index 00000000..4b7b0e4b --- /dev/null +++ b/runsql/example/jndi.properties @@ -0,0 +1,2 @@ +java.naming.factory.initial=com.generationjava.jndi.PropertiesFactory +com.generationjava.jndi.root=config/ diff --git a/runsql/example/sql/BOOTSTRAP.sql b/runsql/example/sql/BOOTSTRAP.sql new file mode 100644 index 00000000..9373894c --- /dev/null +++ b/runsql/example/sql/BOOTSTRAP.sql @@ -0,0 +1,4 @@ +INSERT INTO Report (name, sql, age) VALUES ('foo', 'select foo', '95'); +INSERT INTO Report (name, sql, age) VALUES ('bar', 'select poo', '5'); +INSERT INTO Report (name, sql, age) VALUES ('poo', 'delete foo', '9'); +INSERT INTO Report (name, sql, age) VALUES ('barry', 'select wfoo', '9191'); diff --git a/runsql/example/sql/CHECK.sql b/runsql/example/sql/CHECK.sql new file mode 100644 index 00000000..9be0a1fc --- /dev/null +++ b/runsql/example/sql/CHECK.sql @@ -0,0 +1 @@ +SELECT count(*) AS total FROM Report diff --git a/runsql/example/sql/QUERY.sql b/runsql/example/sql/QUERY.sql new file mode 100644 index 00000000..f8cb6ce8 --- /dev/null +++ b/runsql/example/sql/QUERY.sql @@ -0,0 +1 @@ +SELECT * FROM Bandwidth diff --git a/runsql/example/sql/SCHEMA.sql b/runsql/example/sql/SCHEMA.sql new file mode 100644 index 00000000..bba7192d --- /dev/null +++ b/runsql/example/sql/SCHEMA.sql @@ -0,0 +1,11 @@ +DROP TABLE Bandwidth; +CREATE TABLE Bandwidth ( + last_total varchar(255), + this_total varchar(255), + last_in varchar(255), + this_in varchar(255), + last_out varchar(255), + this_out varchar(255), + last_sess varchar(255), + this_sess varchar(255) +); diff --git a/runsql/project.properties b/runsql/project.properties new file mode 100644 index 00000000..18a9eb1e --- /dev/null +++ b/runsql/project.properties @@ -0,0 +1,6 @@ +maven.checkstyle.header.file=/dev/null +maven.repo.remote=http://www.generationjava.com/jars/,http://www.ibiblio.org/maven/ + +maven.ui.banner.background=#000 +maven.ui.section.background=#000 +maven.ui.subsection.background=#000 diff --git a/runsql/project.xml b/runsql/project.xml new file mode 100644 index 00000000..f07a0e21 --- /dev/null +++ b/runsql/project.xml @@ -0,0 +1,92 @@ + + + + 3 + runsql + runsql + 0.1 + + GenerationJava + http://www.generationjava.com/ + /images/initials.jpg + + 2003 + org.osjava.runsql + /images/core-logo.jpg + + + A command line runner of SQL statements. I like piping sql statements into the mysql command on a unix machine. This is designed to let me do the same things in a database independent way. + + + SQL Script Runner + + http://www.osjava.org/runsql/ + www.osjava.org/runsql + /sites/org/osjava/www/runsql/ + /sites/org/osjava/www/builds/releases/runsql/ + + + scm:cvshen@umbongo.flamefew.net:/var/cvs:runsql + http://www.generationjava.com/view-cvs/viewcvs.cgi/runsql/ + + + + + 0.1 + 0.1 + HEAD + + + + + + + + + + + + Henri Yandell + hen + bayard@generationjava.com + GenerationJava + + Java Developer + + + + + + + + commons-dbutils + SNAPSHOT + + + genjava-core + 2.0 + http://www.generationjava.com/projects/GenJavaCore.shtml + + + commons-lang + 1.0 + http://jakarta.apache.org/commons/lang.html + + + + + + bayard@www.generationjava.com + + src/java + + src/test + + + + diff --git a/runsql/src/java/org/osjava/runsql/RunSql.java b/runsql/src/java/org/osjava/runsql/RunSql.java new file mode 100644 index 00000000..27885c7d --- /dev/null +++ b/runsql/src/java/org/osjava/runsql/RunSql.java @@ -0,0 +1,67 @@ +package org.osjava.runsql; + +import java.io.*; +import java.sql.*; +import javax.sql.*; +import javax.naming.*; +import org.apache.commons.dbutils.*; +import org.apache.commons.lang.*; +import com.generationjava.io.*; + +public class RunSql { + + static public void main(String[] args) throws Exception { + String dsname = args[0]; + InitialContext ctxt = new InitialContext(); + DataSource ds = (DataSource)ctxt.lookup(dsname); + Connection conn = ds.getConnection(); + try { + runScript(conn, System.in); + } catch(SQLException sqle) { + System.err.println("Script failure. "); + sqle.printStackTrace(); + } finally { + DbUtils.closeQuietly(conn); + } + } + + static public void runScript(Connection conn, InputStream in) throws SQLException { + runScript(conn, FileW.loadFile(in)); + } + + static public void runScript(Connection conn, String script) throws SQLException { + // TODO: Improve so a ; inside a string is ignored. + String[] stmts = StringUtils.split(script, ";"); + Statement stmt = conn.createStatement(); + try { + for(int i=0; i + + + 3 + scraping-engine + scraping-engine + 0.1 + + GenerationJava + http://www.generationjava.com/ + /images/initials.jpg + + 2003 + com.generationjava.jndi + /images/core-logo.jpg + + + scraping-engine + + + A simple implementation of JNDI. It is entirely library based, so no server instances are started, and it sits upon Java .properties files, so it is easy to use and simple to understand. The .properties files may be either on the file system or in the classpath. + + + A JNDI implementation using .properties + + http://www.generationjava.com/ + + www.generationjava.com/maven/scraping-engine + /sites/com/generationjava/www/maven/genjava/scraping-engine/ + /sites/com/generationjava/www/maven/builds/ + + + scm:cvshen@umbongo.flamefew.net:/var/cvs:scraping-engine + http://www.generationjava.com/view-cvs/viewcvs.cgi/scraping-engine/ + + + + + 1.0 + 1.0 + HEAD + + + + + + + + + + + + Henri Yandell + hen + bayard@generationjava.com + GenerationJava + + Java Developer + + + + + + + + + + + + + log4j + 1.2.7 + http://jakarta.apache.org/log4j/ + + + commons-lang + 1.0 + http://jakarta.apache.org/commons/lang.html + + + commons-httpclient + 2.0-alpha2 + http://jakarta.apache.org/commons/ + + + commons-collections + 2.1 + http://jakarta.apache.org/commons/ + + + commons-dbutils + SNAPSHOT + http://jakarta.apache.org/commons/ + + + genjava-core + 2.0 + http://www.generationjava.com/ + + + simple-jndi + 0.5 + http://www.generationjava.com/ + + + quartz + 1.0.7 + http://www.part.net/quartz.html + + + + + + bayard@www.generationjava.com + + src/java + + src/test + + + + + + + include = *.dtd + include = log4j.properties + + + + + + + diff --git a/scraping-engine/run.sh b/scraping-engine/run.sh new file mode 100755 index 00000000..92290745 --- /dev/null +++ b/scraping-engine/run.sh @@ -0,0 +1 @@ +java -classpath .:target/scraping-engine-0.1.jar:/usr/local/javalib/commons-collections-2.1.jar:/usr/local/javalib/commons-lang-1.0.1.jar:/usr/local/javalib/genjava-core-2.0.jar:config/:/usr/local/javalib/maven/repository/simple-jndi/jars/simple-jndi-0.5.jar:/usr/local/javalib/commons-httpclient-2.0-alpha2.jar:/usr/local/javalib/commons-logging-1.0.1.jar:/usr/local/javalib/maven/repository/commons-dbutils/jars/commons-dbutils-SNAPSHOT.jar:/usr/local/javalib/mm.mysql-2.0.9-bin.jar:/Users/hen/Desktop/hsqldb/lib/hsqldb.jar:/usr/local/javalib/maven/repository/log4j/jars/log4j-1.2.7.jar:/usr/local/javalib/maven/repository/quartz/jars/quartz-1.0.7.jar org.osjava.scraping.Engine diff --git a/scraping-engine/runc.sh b/scraping-engine/runc.sh new file mode 100755 index 00000000..6837e24d --- /dev/null +++ b/scraping-engine/runc.sh @@ -0,0 +1 @@ +javac -classpath /usr/local/javalib/commons-lang-1.0.1.jar:/usr/local/javalib/genjava-core-2.0.jar:target/scraping-engine-0.1.jar:.:/usr/local/javalib/maven/repository/log4j/jars/log4j-1.2.7.jar com/*/scraper/*.java diff --git a/scraping-engine/src/java/org/osjava/scraping/AbstractConfig.java b/scraping-engine/src/java/org/osjava/scraping/AbstractConfig.java new file mode 100644 index 00000000..0ef2a1aa --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/AbstractConfig.java @@ -0,0 +1,70 @@ +package org.osjava.scraping; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang.NumberUtils; +import java.util.Date; + +public abstract class AbstractConfig implements Config { + + private String context = ""; + + protected abstract Object getValue(String key); + + public Object get(String key) { + return getValue( getContext()+key ); + } + + public boolean has(String key) { + return (get(key) != null); + } + + public Object getAbsolute(String key) { + return getValue(key); + } + + public String getString(String key) { + return (String)get(key); + } + + public Date getDate(String key) { + try { + return java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT).parse(key); + } catch(java.text.ParseException pe) { + return null; + } + } + + // rely on simple-jndi's type + public int getInt(String key) { + return NumberUtils.stringToInt(getString(key)); + } + + public List getList(String key) { + Object obj = get(key); + if(!(obj instanceof List)) { + List list = new ArrayList(1); + list.add(obj); + obj = list; + } + return (List)obj; + } + + public void setContext(String context) { + this.context = context; + } + + public String getContext() { + return this.context; + } + + public Config cloneConfig() { + try { + return (Config)this.clone(); + } catch(CloneNotSupportedException cnse) { + // ignore + throw new RuntimeException("Cloning of a Config failed. This should be impossible. "); + } + } + +} diff --git a/scraping-engine/src/java/org/osjava/scraping/AbstractPage.java b/scraping-engine/src/java/org/osjava/scraping/AbstractPage.java new file mode 100644 index 00000000..7aec7eab --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/AbstractPage.java @@ -0,0 +1,66 @@ +package org.osjava.scraping; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +import java.io.BufferedReader; + +import org.apache.log4j.Logger; + +public abstract class AbstractPage implements Page { + + private static Logger logger = Logger.getLogger(AbstractPage.class); + + private String documentBase; + + public AbstractPage() { + } + + public abstract Reader read() throws IOException; + + public Page fetch(String uri, Config cfg, Session session) throws FetchingException { + int idx = uri.indexOf("://"); + if(idx == -1) { + // TODO: also check it is less than 15 or something?? + uri = this.documentBase + "/" + uri; + } + logger.debug("Fetching: "+uri); + Fetcher fetcher = FetchingFactory.getFetcher(cfg, session); + Page page = fetcher.fetch(uri, cfg, session); + return page; + } + + public void setDocumentBase(String documentBase) { + logger.debug("Document base: "+documentBase); + this.documentBase = documentBase; + } + + public String getDocumentBase() { + return this.documentBase; + } + + public String readAsString() throws IOException { + Reader rdr = null; + try { + rdr = this.read(); + BufferedReader bfr = new BufferedReader(rdr); + StringBuffer buffer = new StringBuffer(); + String line = ""; + while( (line = bfr.readLine()) != null) { + buffer.append(line); + buffer.append("\n"); + } + return buffer.toString(); + } finally { + if(rdr != null) { + try { + rdr.close(); + } catch(IOException ioe) { + // ignore + } + } + } + } + +} diff --git a/scraping-engine/src/java/org/osjava/scraping/AbstractParser.java b/scraping-engine/src/java/org/osjava/scraping/AbstractParser.java new file mode 100644 index 00000000..3ed3099d --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/AbstractParser.java @@ -0,0 +1,13 @@ +package org.osjava.scraping; + +public abstract class AbstractParser implements Parser { + + abstract public Result parse(Page page, Config cfg, Session session) throws ParsingException; + + public void startUp(Config cfg) throws Exception { } + public void bringDown(Config cfg) throws Exception { } + + // helper methods + // ?? + +} diff --git a/scraping-engine/src/java/org/osjava/scraping/CheckingParser.java b/scraping-engine/src/java/org/osjava/scraping/CheckingParser.java new file mode 100644 index 00000000..3344505d --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/CheckingParser.java @@ -0,0 +1,23 @@ +package org.osjava.scraping; + +public abstract class CheckingParser extends AbstractParser { + + public Result parse(Page page, Config cfg, Session session) throws ParsingException { + Header header = parseHeader(page, cfg, session); + Store store = StoreFactory.getStore(cfg, session); + try { + boolean found = store.exists(header, cfg, session); + if(found) { + return new NullResult(); + } else { + return parseBody(page, header, cfg, session); + } + } catch(StoringException se) { + return new NullResult(); + } + } + + public abstract Header parseHeader(Page page, Config cfg, Session session) throws ParsingException; + public abstract Result parseBody(Page page, Header header, Config cfg, Session session) throws ParsingException; + +} diff --git a/scraping-engine/src/java/org/osjava/scraping/Config.java b/scraping-engine/src/java/org/osjava/scraping/Config.java new file mode 100644 index 00000000..088fa178 --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/Config.java @@ -0,0 +1,19 @@ +package org.osjava.scraping; + +import java.util.List; +import java.util.Date; + +public interface Config extends Cloneable { + + public Object get(String key); + public boolean has(String key); + public Object getAbsolute(String key); + public String getString(String key); + public int getInt(String key); + public Date getDate(String key); + public List getList(String key); + public void setContext(String context); + public String getContext(); + public Config cloneConfig(); + +} diff --git a/scraping-engine/src/java/org/osjava/scraping/ConfigFactory.java b/scraping-engine/src/java/org/osjava/scraping/ConfigFactory.java new file mode 100644 index 00000000..e501d1e6 --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/ConfigFactory.java @@ -0,0 +1,9 @@ +package org.osjava.scraping; + +public class ConfigFactory { + + static public Config getConfig(String[] args) { + return new JndiConfig(); + } + +} diff --git a/scraping-engine/src/java/org/osjava/scraping/Engine.java b/scraping-engine/src/java/org/osjava/scraping/Engine.java new file mode 100644 index 00000000..fa78e367 --- /dev/null +++ b/scraping-engine/src/java/org/osjava/scraping/Engine.java @@ -0,0 +1,93 @@ +package org.osjava.scraping; + +import java.util.List; +import java.io.Reader; + +public class Engine implements Runner { + + public static void main(String[] args) { + Engine engine = new Engine(); + engine.run(args); + } + +/// TODO: Implement the Scheduler aspect +/// The Scheduler notifies only this class. It is +/// then up to this Engine to run the parsers. +/// TODO: Put the scraping and db in a different thread + public void run(String[] args) { + // load the config + Config cfg = ConfigFactory.getConfig(args); + + + // test and how schedule=startup will be handled + List list = cfg.getList("org.osjava.scrapers"); + for(int i=0; i