You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rd...@apache.org on 2002/02/25 20:07:15 UTC

cvs commit: jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id AbstractIDGenerator.java RandomIDGenerator.java SequentialIDGenerator.java package.html

rdonkin     02/02/25 11:07:15

  Modified:    betwixt/src/java/org/apache/commons/betwixt XMLBeanInfo.java
                        XMLIntrospector.java
               betwixt/src/java/org/apache/commons/betwixt/io
                        BeanWriter.java
  Added:       betwixt/src/java/org/apache/commons/betwixt/io
                        IDGenerator.java
               betwixt/src/java/org/apache/commons/betwixt/io/id
                        AbstractIDGenerator.java RandomIDGenerator.java
                        SequentialIDGenerator.java package.html
  Log:
  Implemented ID/IDREF solution to cyclic reference problem
  
  Revision  Changes    Path
  1.5       +50 -6     jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java
  
  Index: XMLBeanInfo.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XMLBeanInfo.java	19 Feb 2002 06:10:26 -0000	1.4
  +++ XMLBeanInfo.java	25 Feb 2002 19:07:15 -0000	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java,v 1.4 2002/02/19 06:10:26 jstrachan Exp $
  - * $Revision: 1.4 $
  - * $Date: 2002/02/19 06:10:26 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java,v 1.5 2002/02/25 19:07:15 rdonkin Exp $
  + * $Revision: 1.5 $
  + * $Date: 2002/02/25 19:07:15 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: XMLBeanInfo.java,v 1.4 2002/02/19 06:10:26 jstrachan Exp $
  + * $Id: XMLBeanInfo.java,v 1.5 2002/02/25 19:07:15 rdonkin Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -68,14 +68,18 @@
     * or XSLT for example.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.4 $
  +  * @version $Revision: 1.5 $
     */
   public class XMLBeanInfo {
  -
  +    /** Descriptor for main element */
       private ElementDescriptor elementDescriptor;
       
       /** the beans class that this XML info refers to */
       private Class beanClass;
  +    /** <code>ID</code> attribute name */
  +    private String idAttributeName = "id";
  +    /** <code>IDREF</code> attribute name */
  +    private String idrefAttributeName = "idref";
       
       /** Base constructor */
       public XMLBeanInfo( Class beanClass ) {
  @@ -100,5 +104,45 @@
       /** Sets the beans class that this XML info refers to */
       public void setBeanClass(Class beanClass) {
           this.beanClass = beanClass;
  +    }
  +    
  +    /** Search attributes for one matching <code>ID</code> attribute name */
  +    public AttributeDescriptor getIDAttribute() {
  +        // XXX this only need to be done once!
  +        // we'll check to see if the bean already has an id
  +        if ( getElementDescriptor().hasAttributes() ) {
  +            AttributeDescriptor[] attributes = getElementDescriptor().getAttributeDescriptors();
  +            if ( attributes != null ) {
  +                for ( int i = 0, size = attributes.length; i < size; i++ ) {
  +                    // support a match either on local or qualified name
  +                    if ( getIDAttributeName().equals( attributes[i].getQualifiedName() ) 
  +                        || getIDAttributeName().equals( attributes[i].getLocalName() )) {
  +                        // we've got a match so use this attribute
  +                        return attributes[i];
  +                        
  +                    }
  +                }
  +            }
  +        }
  +        return null;
  +    }
  +    
  +    /** Get name of <code>ID</code> attribute */
  +    public String getIDAttributeName() {
  +        return idAttributeName;
  +    }
  +    /** Set name of <code>ID</code> attribute */
  +    public void setIDAttributeName(String idAttributeName) {
  +        this.idAttributeName = idAttributeName;
  +    }
  +    
  +    /** Get <code>IDREF</code> attribute name */
  +    public String getIDREFAttributeName() {
  +        return idrefAttributeName;
  +    }
  +    
  +    /** Set <code>IDREF</code> attribute name */
  +    public void setIDREFAttributeName() {
  +        this.idrefAttributeName = idrefAttributeName;
       }
   }
  
  
  
  1.18      +7 -7      jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java
  
  Index: XMLIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- XMLIntrospector.java	19 Feb 2002 15:31:30 -0000	1.17
  +++ XMLIntrospector.java	25 Feb 2002 19:07:15 -0000	1.18
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java,v 1.17 2002/02/19 15:31:30 jstrachan Exp $
  - * $Revision: 1.17 $
  - * $Date: 2002/02/19 15:31:30 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java,v 1.18 2002/02/25 19:07:15 rdonkin Exp $
  + * $Revision: 1.18 $
  + * $Date: 2002/02/25 19:07:15 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: XMLIntrospector.java,v 1.17 2002/02/19 15:31:30 jstrachan Exp $
  + * $Id: XMLIntrospector.java,v 1.18 2002/02/25 19:07:15 rdonkin Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -99,7 +99,7 @@
     * Later requests for the same class will return the cached value.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.17 $
  +  * @version $Revision: 1.18 $
     */
   public class XMLIntrospector {
   
  @@ -416,7 +416,7 @@
       }
   
       /** Returns true if the type is a loop type */
  -    protected boolean isLoopType(Class type) {
  +    public boolean isLoopType(Class type) {
           return type.isArray() 
               || Map.class.isAssignableFrom( type ) 
               || Collection.class.isAssignableFrom( type ) 
  @@ -426,7 +426,7 @@
       
       
       /** Returns true for primitive types */
  -    protected boolean isPrimitiveType(Class type) {
  +    public boolean isPrimitiveType(Class type) {
           if ( type.equals( Object.class ) ) {
               return false;
           }
  
  
  
  1.15      +233 -35   jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java
  
  Index: BeanWriter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- BeanWriter.java	19 Feb 2002 06:10:27 -0000	1.14
  +++ BeanWriter.java	25 Feb 2002 19:07:15 -0000	1.15
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java,v 1.14 2002/02/19 06:10:27 jstrachan Exp $
  - * $Revision: 1.14 $
  - * $Date: 2002/02/19 06:10:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java,v 1.15 2002/02/25 19:07:15 rdonkin Exp $
  + * $Revision: 1.15 $
  + * $Date: 2002/02/25 19:07:15 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: BeanWriter.java,v 1.14 2002/02/19 06:10:27 jstrachan Exp $
  + * $Id: BeanWriter.java,v 1.15 2002/02/25 19:07:15 rdonkin Exp $
    */
   package org.apache.commons.betwixt.io;
   
  @@ -68,6 +68,7 @@
   import java.io.OutputStreamWriter;
   import java.io.Writer;
   import java.util.Iterator;
  +import java.util.HashMap;
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -78,6 +79,7 @@
   import org.apache.commons.betwixt.XMLIntrospector;
   import org.apache.commons.betwixt.expression.Context;
   import org.apache.commons.betwixt.expression.Expression;
  +import org.apache.commons.betwixt.io.id.SequentialIDGenerator;
   
   
   /** <p><code>BeanWriter</code> output beans as XML.</p>
  @@ -97,8 +99,26 @@
     * The output will be indented. 
     * The indent string used is set by {@link #setIndent}.
     *
  +  * <p> Bean graphs can sometimes contain cycles. 
  +  * Care must be taken when serializing cyclic bean graphs
  +  * since this can lead to infinite recursion. 
  +  * The approach taken by <code>BeanWriter</code> is to automatically
  +  * assign an <code>ID</code> attribute value to beans.
  +  * When a cycle is encountered, 
  +  * an element is written that has the <code>IDREF</code> attribute set to the 
  +  * id assigned earlier.
  +  *
  +  * <p> The names of the <code>ID</code> and <code>IDREF</code> attributes used 
  +  * can be customized by the <code>XMLBeanInfo</code>.
  +  * The id's used can also be customized by the user 
  +  * via <code>IDGenerator</code> subclasses.
  +  * The implementation used can be set by the <code>IdGenerator</code> property.
  +  * BeanWriter defaults to using <code>SequentialIDGenerator</code> 
  +  * which supplies id values in numeric sequence.
  +  * 
  +  * 
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.14 $
  +  * @version $Revision: 1.15 $
     */
   public class BeanWriter {
   
  @@ -127,6 +147,10 @@
       private boolean autoFlush;
       /** Log used for logging (Doh!) */
       private Log log = LogFactory.getLog( BeanWriter.class );
  +    /** Map containing ID attribute values for beans */
  +    private HashMap idMap = new HashMap();
  +    /** Used to generate ID attribute values*/
  +    private IDGenerator idGenerator = new SequentialIDGenerator();
       
       /**
        * <p> Constructor uses <code>System.out</code> for output.</p>
  @@ -162,20 +186,16 @@
        * @param bean write out representation of this bean
        */
       public void write(Object bean) throws IOException, IntrospectionException  {
  -        log.debug("Writing bean graph...");
  -        XMLBeanInfo beanInfo = introspector.introspect( bean );
  -        if ( beanInfo != null ) {
  -            ElementDescriptor elementDescriptor = beanInfo.getElementDescriptor();
  -            if ( elementDescriptor != null ) {
  -                Context context = new Context( bean, log );
  -                write( elementDescriptor.getQualifiedName(), elementDescriptor, context );
  -            }
  -        }
  +        log.debug( "Writing bean graph..." );
  +        log.debug( bean );
           
  +        write( null, bean );
  +
           if ( autoFlush ) {
               writer.flush();
           }
  -        log.debug("Finished writing bean graph.");
  +        
  +        log.debug( "Finished writing bean graph." );
       }
       
       /** Writes the given bean to the current stream using the given <code>qualifiedName</code> */
  @@ -185,9 +205,11 @@
                       throws 
                           IOException, 
                           IntrospectionException {
  -        if (log.isDebugEnabled())
  +                    
  +        
  +        if ( log.isTraceEnabled() )
           {
  -            log.debug("Writing bean graph (qualified name '" + qualifiedName + "'");
  +            log.trace( "Writing bean graph (qualified name '" + qualifiedName + "'" );
           }
           
           // introspect to obtain bean info
  @@ -199,11 +221,63 @@
                   if ( qualifiedName == null ) {
                       qualifiedName = elementDescriptor.getQualifiedName();
                   }
  -                write( qualifiedName, elementDescriptor, context );
  +                
  +                Object ref = null;
  +                Object id = null;
  +                
  +                // only give id's to non-primatives
  +                if ( elementDescriptor.isPrimitiveType() ) {
  +                        // write without an id
  +                        write( 
  +                            qualifiedName, 
  +                            elementDescriptor, 
  +                            context );
  +                } 
  +                else {
  +                
  +                    ref = idMap.get( context.getBean() );
  +                    if ( ref == null ) {
  +                        // this is the first time that this bean has be written
  +                        AttributeDescriptor idAttribute = beanInfo.getIDAttribute();
  +                        if (idAttribute == null) {
  +                            // use a generated id
  +                            id = new Integer( idGenerator.nextId() );
  +                            idMap.put( bean, id);
  +                            
  +                            // write element with id
  +                            write( 
  +                                qualifiedName, 
  +                                elementDescriptor, 
  +                                context , 
  +                                beanInfo.getIDAttributeName(),
  +                                id.toString());
  +                                                        
  +                        } else {
  +                            // use id from bean property
  +                            // it's up to the user to ensure uniqueness
  +                            // XXX should we trap nulls?
  +                            id = idAttribute.getTextExpression().evaluate( context );
  +                            idMap.put( bean, id);
  +                            
  +                            // the ID attribute should be written automatically
  +                            write( 
  +                                qualifiedName, 
  +                                elementDescriptor, 
  +                                context );
  +                        }
  +                    } 
  +                    else {
  +                        // we've already written this bean so write an IDREF
  +                        writeIDREFElement( 
  +                                        qualifiedName,  
  +                                        beanInfo.getIDREFAttributeName(), 
  +                                        ref.toString());
  +                    }
  +                }
               }
           }
           
  -        log.debug("Finished writing bean graph.");
  +        log.trace( "Finished writing bean graph." );
       }
   
       /**
  @@ -234,6 +308,17 @@
       public void setIndent(String indent) {
           this.indent = indent;
       }
  +    
  +    /** Get IDGenerator used to generate ID attribute values */
  +    public IDGenerator getIdGenerator() {
  +        return idGenerator;
  +    }
  +    
  +    /** Set IDGenerator used to generate ID attribute values */
  +    public void setIdGenerator(IDGenerator idGenerator) {
  +        this.idGenerator = idGenerator;
  +    }
  +    
   
   
       /**
  @@ -276,7 +361,81 @@
       public void setLog(Log log) {
           this.log = log;
       }
  +    
  +        
  +    // Expression methods
  +    //-------------------------------------------------------------------------    
  +
  +    /** Express an element tag start using given qualified name */
  +    protected void expressElementStart(String qualifiedName) throws IOException {
  +        if ( qualifiedName == null ) {
  +            // XXX this indicates a programming error
  +            log.fatal( "[expressElementStart]Qualified name is null." );
  +            throw new RuntimeException( "Qualified name is null." );
  +        }
  +        
  +        writePrintln();
  +        writeIndent();
  +        writer.write( "<" );
  +        writer.write( qualifiedName );
  +    }
  +    
  +    /** Express an element end tag using given qualifiedName */
  +    protected void expressElementEnd(String qualifiedName) throws IOException {
  +        if (qualifiedName == null) {
  +            // XXX this indicates a programming error
  +            log.fatal( "[expressElementEnd]Qualified name is null." );
  +            throw new RuntimeException( "Qualified name is null." );
  +        }
  +        
  +        writer.write( "</" );
  +        writer.write( qualifiedName );
  +        writer.write( ">" );
  +    }    
  +    
  +    /** Express an empty element end */
  +    protected void expressElementEnd() throws IOException {
  +        writer.write( "/>" );
  +    }
  +
  +    /** Express body text */
  +    protected void expressBodyText(String text) throws IOException {
  +        writer.write( ">" );
  +        if ( text == null ) {
  +            // XXX This is probably a programming error
  +            log.error( "[expressBodyText]Body text is null" );
  +            
  +        } else {
  +            writer.write( text );
  +        }
  +    }
  +    
  +    /** Express an attribute */
  +    protected void expressAttribute(
  +                                String qualifiedName, 
  +                                String value) 
  +                                    throws
  +                                        IOException{
  +        if ( value == null ) {
  +            // XXX probably a programming error
  +            log.error( "Null attribute value." );
  +            return;
  +        }
           
  +        if ( qualifiedName == null ) {
  +            // XXX probably a programming error
  +            log.error( "Null attribute value." );
  +            return;
  +        }
  +                
  +        writer.write( " " );
  +        writer.write( qualifiedName );
  +        writer.write( "=\"" );
  +        writer.write( value );
  +        writer.write( "\"" );
  +    }
  +
  +
       // Implementation methods
       //-------------------------------------------------------------------------    
       
  @@ -289,21 +448,65 @@
                                   throws 
                                       IOException, 
                                       IntrospectionException {
  -        writePrintln();
  -        writeIndent();
  -        writer.write( "<" );
  -        writer.write( qualifiedName );
  +        expressElementStart( qualifiedName );
  +        
  +        writeRestOfElement( qualifiedName, elementDescriptor, context);
  +    }
  +    
  +    
  +
  +    /** Writes the given element adding an ID attribute */
  +    protected void write( 
  +                            String qualifiedName, 
  +                            ElementDescriptor elementDescriptor, 
  +                            Context context,
  +                            String idAttribute,
  +                            String idValue ) 
  +                                throws 
  +                                    IOException, 
  +                                    IntrospectionException {
  +                                  
  +        expressElementStart( qualifiedName );
  +             
  +        expressAttribute( idAttribute, idValue );        
  +        
  +        writeRestOfElement( qualifiedName, elementDescriptor, context );
  +    }
  +    
  +    /** Write attributes, child elements and element end */
  +    protected void writeRestOfElement( 
  +                            String qualifiedName, 
  +                            ElementDescriptor elementDescriptor, 
  +                            Context context ) 
  +                                throws 
  +                                    IOException, 
  +                                    IntrospectionException {
  +
           writeAttributes( elementDescriptor, context );
           
           if ( writeContent( elementDescriptor, context ) ) {
  -            writer.write( "</" );
  -            writer.write( qualifiedName );
  -            writer.write( ">" );
  -        }
  +            expressElementEnd( qualifiedName );
  +        }  
           else {            
  -            writer.write( "/>" );
  +            expressElementEnd();
           }
       }
  +    
  +    protected void writeIDREFElement( 
  +                                    String qualifiedName, 
  +                                    String idrefAttributeName,
  +                                    String idrefAttributeValue ) 
  +                                        throws 
  +                                            IOException, 
  +                                            IntrospectionException {
  +
  +        // write IDREF element
  +        expressElementStart( qualifiedName );
  +        
  +        expressAttribute( idrefAttributeName, idrefAttributeValue );
  +                             
  +        expressElementEnd();
  +    }
           
       /** Writes the element content.
        *
  @@ -357,8 +560,7 @@
                   if ( value != null ) {
                       String text = escapeBodyValue(value);
                       if ( text != null && text.length() > 0 ) {
  -                        writer.write( ">" );
  -                        writer.write( text );
  +                        expressBodyText(text);
                           answer = true;
                       }
                   }                
  @@ -395,11 +597,7 @@
               if ( value != null ) {
                   String text = escapeAttributeValue(value);
                   if ( text != null && text.length() > 0 ) {
  -                    writer.write( " " );
  -                    writer.write( attributeDescriptor.getQualifiedName() );
  -                    writer.write( "=\"" );
  -                    writer.write( text );
  -                    writer.write( "\"" );
  +                    expressAttribute(attributeDescriptor.getQualifiedName(), text);
                   }
               }                
           }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/IDGenerator.java
  
  Index: IDGenerator.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/IDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/25 19:07:15 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. 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.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: IDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   */
  package org.apache.commons.betwixt.io;
  
  
  /** <p>Interface allowing pluggable <code>ID</code> generators.</p>
    *
    * <p> <code>IDGenerator</code>'s are used to generate <code>ID</code>
    * attribute values by <code>BeanWriter</code>. 
    * Generators have been created that supply random and sequantial values.</p>
    *
    * @author <a href="mailto:rdonkin@apache.org">Robert Burrell Donkin</a>
    * @version $Revision: 1.1 $
    */
  public interface IDGenerator {
      
      /** Get the last id produced */
      public int getLastId();
      
      /** Generate id */
      public int nextId();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/AbstractIDGenerator.java
  
  Index: AbstractIDGenerator.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/AbstractIDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/25 19:07:15 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. 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.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: AbstractIDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   */
  package org.apache.commons.betwixt.io.id;
  
  import org.apache.commons.betwixt.io.IDGenerator;
  
  /** <p> Abstract superclass for id generator implementations.
    * Provides utility methods that store the last id generated.
    * Sub class should override {@link #nextIdImpl}.</p>
    *
    * @author <a href="mailto:rdonkin@apache.org">Robert Burrell Donkin</a>
    * @version $Revision: 1.1 $
    */
  public abstract class AbstractIDGenerator implements IDGenerator {
      
      /** Last id returned */
      private int lastId = 0;
      
      /** Get last if implementation */
      public final int getLastId() {
          return lastId;
      }
      
      /** Generate next id */
      public final int nextId() {
          lastId = nextIdImpl();
          return lastId;
      }
      
      /** Subclasses overried this method */
      protected abstract int nextIdImpl();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/RandomIDGenerator.java
  
  Index: RandomIDGenerator.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/RandomIDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/25 19:07:15 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. 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.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: RandomIDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   */
  package org.apache.commons.betwixt.io.id;
  
  import java.util.Random;
  
  /** <p>Generates random ids.
    * This class can generate positive-only ids (the default)
    * or it can generate a mix of negative and postive ones.
    *
    * @author <a href="mailto:rdonkin@apache.org">Robert Burrell Donkin</a>
    * @version $Revision: 1.1 $
    */
  public final class RandomIDGenerator extends AbstractIDGenerator {
      
      /** Use simple java.util.Random as the source for our numbers */
      private Random random = new Random();
      /** Should only positive id's be generated? */
      private boolean onlyPositiveIds = true;
          
      /** Base constructor */
      public RandomIDGenerator() {} 
      
      /** Construct sets PositiveIds property */
      public RandomIDGenerator(boolean onlyPositiveIds) {
          setPositiveIds(onlyPositiveIds);
      }
      
      /** Next id implementation */
      public int nextIdImpl() {
          int next = random.nextInt();
          if (onlyPositiveIds && next<0) {
              // it's negative and we're ignoring them so get another
              return nextIdImpl();
          }
          return next;
      }
      
      /** Get whether only positive id's should be generated */
      public boolean getPositiveIds() {
          return onlyPositiveIds;
      }
      
      /** Set whether only positive id's should be generated */
      public void setPositiveIds(boolean onlyPositiveIds) {
          this.onlyPositiveIds = onlyPositiveIds;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/SequentialIDGenerator.java
  
  Index: SequentialIDGenerator.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/SequentialIDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/25 19:07:15 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. 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.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: SequentialIDGenerator.java,v 1.1 2002/02/25 19:07:15 rdonkin Exp $
   */
  package org.apache.commons.betwixt.io.id;
  
  
  /** <p>This simply uses a counting mechanism to assign id's</p>
    *
    * @author <a href="mailto:rdonkin@apache.org">Robert Burrell Donkin</a>
    * @version $Revision: 1.1 $
    */
  public final class SequentialIDGenerator extends AbstractIDGenerator {
      
      /** Counter used to assign id's */
      private int counter = 0;
          
      /** Base constructor */
      public SequentialIDGenerator() {} 
      
      /** Set the start value for the sequence */
      public SequentialIDGenerator(int start) {
          this.counter = start;
      }
      
      /** Next id implementation */
      public int nextIdImpl() {
          return ++counter;
      }
      
      /** Get the current counter value */
      public int getCount() {
          return counter;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/id/package.html
  
  Index: package.html
  ===================================================================
  <html>
  <head>
  </head>
  <body>
  
    <p>This package is home to <code>IDGenerator</code> implementations.
    </p>
    
  </body>
  </html>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>