Package com.draagon.meta.manager.xml

Source Code of com.draagon.meta.manager.xml.ObjectManagerXML

/*
* Copyright 2003 Draagon Software LLC. All Rights Reserved.
*
* This software is the proprietary information of Draagon Software LLC.
* Use is subject to license terms.
*/

package com.draagon.meta.manager.xml;

import com.draagon.meta.*;
import com.draagon.meta.manager.*;
import com.draagon.meta.manager.exp.Expression;
import com.draagon.meta.manager.exp.Range;
import com.draagon.meta.manager.exp.SortOrder;
import com.draagon.util.xml.XMLFileReader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.util.*;

// import javax.servlet.*;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

//import org.xml.sax.InputSource;
//import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
//import org.xml.sax.SAXParseException;
//import org.xml.sax.SAXNotRecognizedException;
//import org.xml.sax.SAXNotSupportedException;

/**
* The Object Manager Base is able to add, update, delete,
* and retrieve objects of those types from a datastore.
*/
public class ObjectManagerXML extends ObjectManager
{
  private static Log log = LogFactory.getLog( ObjectManagerXML.class );

  private Map<MetaClass,List<Object>> tables = new Hashtable<MetaClass,List<Object>>();
  private String mRoot = null;

  public ObjectManagerXML()
  {
  }

  public void setLocation( String root )
  {
        mRoot = root;
    }

    public String getLocation()
    {
        return mRoot;
    }


    ///////////////////////////////////////////////////////
    // CONNECTION HANDLING METHODS
    //

  /**
   * Retrieves a connection object representing the datastore
   */
  public ObjectConnection getConnection()
    throws MetaException
    {
        return new ObjectConnectionXML( tables );
    }

  public void releaseConnection( ObjectConnection oc )
    throws MetaException
    {
    oc.close();
    }


    ///////////////////////////////////////////////////////
    // PERSISTENCE METHODS
    //

  /** Is this a createable class */       
  public boolean isCreateableClass( MetaClass mc ) {
            return true;
        }

  /** Is this a readable class */
  public boolean isReadableClass( MetaClass mc ) {
            return true;
        }

  /** Gets the update mapping to the DB */
  public boolean isUpdateableClass( MetaClass mc ) {
            return true;
        }

  /** Gets the delete mapping to the DB */
  public boolean isDeleteableClass( MetaClass mc ) {
            return true;
        }
       
    //protected MappingHandler getDefaultMappingHandler() {
    //  return new SimpleMappingHandlerXML();
    //}
 
  /**
   * Retrieves the fields of a MetaClass which are persistable
   */
  @SuppressWarnings("unchecked")
  public Collection<MetaField> getWriteableFields( MetaClass mc )
  {
      final String KEY = "getWriteableFields()";

      ArrayList<MetaField> fields = (ArrayList<MetaField>) mc.getCacheValue( KEY );

      if ( fields == null )
      {
          fields = new ArrayList<MetaField>();

          for( Iterator i = mc.getMetaFields().iterator(); i.hasNext(); )
          {
              MetaField f = (MetaField) i.next();
              if ( isWriteableField( f )) fields.add( f );
          }

          mc.setCacheValue( KEY, fields );
      }

  /*if ( fields.size() == 0 )
    throw new MetaException( "No persistable fields for MetaClass [" + mc + "]" );*/

      return fields;
  }
 

  /**
   * Retrieves the fields of a MetaClass which are persistable
   */
  @SuppressWarnings("unchecked")
  public Collection<MetaField> getReadableFields( MetaClass mc )
  {
      final String KEY = "getReadableFields()";

      ArrayList<MetaField> fields = (ArrayList<MetaField>) mc.getCacheValue( KEY );

      if ( fields == null )
      {
          fields = new ArrayList<MetaField>();

          for( Iterator i = mc.getMetaFields().iterator(); i.hasNext(); )
          {
              MetaField f = (MetaField) i.next();
              if ( isReadableField( f )) fields.add( f );
          }

          mc.setCacheValue( KEY, fields );
      }

      /*if ( fields.size() == 0 )
          throw new MetaException( "No persistable fields for MetaClass [" + mc + "]" );*/

      return fields;
  }

    /**
     * Returns whether the metafield is persistable or not
     */
    public boolean isReadableField( MetaField mf )
    {
      return true;
    }

    /**
     * Returns whether the metafield is persistable or not
     */
    public boolean isWriteableField( MetaField mf )
    {
      if ( isReadOnly( mf )) return false;
      return true;
    }

    protected String getNextFieldId( ObjectConnection c, MetaClass mc, MetaField f ) throws MetaException
    {
        long id = 0;
        List<Object> list = getObjectsFromTable( c, mc );

        for( Object o : list )
        {
            Long l = f.getLong( o );
            if ( l == null ) l = new Long( 1 );

            if ( l.longValue() > id ) id = l.longValue();
        }

        return "" + ( id + 1 );
    }

  public void handleAutoField( ObjectConnection c, MetaClass mc, MetaField mf, Object obj, Object auto, int state, int action )
    throws MetaException
  {
    if ( "id".equals( auto ) && action == CREATE && state == AUTO_PRIOR ) {
      mf.setString( obj, getNextFieldId( c, mc, mf ));
    }

    super.handleAutoField( c, mc, mf, obj, auto, state, action );
  }


  /**
   * Gets the object by the id; throws exception if it did not exist
   */
  public Object getObjectByRef( ObjectConnection c, String refStr )
    throws MetaException
    {
        ObjectRef ref = getObjectRef( refStr );
        MetaClass mc = ref.getMetaClass();

        for( Object o : getObjectsFromTable( c, mc )) {
            if ( getObjectRef( o ).equals( ref )) return o;
        }

        throw new ObjectNotFoundException( "Object of class [" + mc + "] with reference [" + ref + "] was not found" );
    }

  /**
   * Get all objects of the specified kind from the datastore
   */
  public Collection<Object> getObjects( ObjectConnection c, MetaClass mc, QueryOptions options )
    throws MetaException
    {
        Collection<Object> objs = getObjectsFromTable( c, mc );

        // Get the fields to copy
        Collection<MetaField> fields = options.getFields();
        if ( fields == null || fields.size() == 0 ) {
          //if ( options.getWriteableOnly() )
          //  fields = getWriteableFields( mc );
          //else
            fields = getReadableFields( mc );
        }

        // Copy all the objects and only the specified fields
        Collection<Object> results = new ArrayList<Object>();
        for( Object o1 : objs )
        {
          Object o2 = mc.newInstance();

          for( MetaField f : fields ) {
            f.setObject( o2, f.getObject( o1 ));
          }

          results.add( o2 );
        }


        // Handle Expressions, Sorting, Ranging, and Options
        Expression exp = options.getExpression();
        SortOrder sort = options.getSortOrder();
        Range range = options.getRange();

        if ( exp != null )
            results = filterObjects( results, exp );

        if ( sort != null )
            results = sortObjects( results, sort );

        if ( range != null )
            results = clipObjects( results, range );

        if( options.isDistinct() )
            results = distinctObjects( results );

        return results;
    }

  /**
   * Load the specified object from the XML source
   */
  public void loadObject( ObjectConnection c, Object obj )
    throws MetaException
    {
        String ref = getObjectRef( obj ).toString();

        Object o = getObjectByRef( c, ref );

        for( MetaField mf : getReadableFields( MetaClassLoader.findMetaClass( obj )))
        {
          if ( !isPrimaryKey( mf ))
            mf.setObject( obj, mf.getObject( o ));
        }
    }

  /**
   * Add the specified object to the datastore
   */
  public void createObject( ObjectConnection c, Object obj )
    throws MetaException
    {
        MetaClass mc = MetaClassLoader.findMetaClass( obj );
        List<Object> list = getObjectsFromTable( c, mc );

        if ( !isCreateableClass( mc ))
          throw new MetaException( "Object of class [" + mc + "] is not persistable" );

        prePersistence( c, mc, obj, CREATE );

        list.add( obj );

        postPersistence( c, mc, obj, CREATE );
    }

  /**
   * Update the specified object in the datastore
   */
  public void updateObject( ObjectConnection c, Object obj )
    throws MetaException
  {
    MetaClass mc = MetaClassLoader.findMetaClass( obj );
    List<Object> list = getObjectsFromTable( c, mc );

    int i = list.indexOf( obj );
    if ( i < 0 )
      throw new MetaException( "Object [" + obj + "] did not exist in table for class [" + mc + "]" );

    if ( !isUpdateableClass( mc ))
      throw new MetaException( "Object of class [" + mc + "] is not persistable" );

    prePersistence( c, mc, obj, UPDATE );

    list.set( i, obj );

    postPersistence( c, mc, obj, UPDATE );
  }

  /**
   * Delete the specified object from the datastore
   */
  public void deleteObject( ObjectConnection c, Object obj )
    throws MetaException
  {
    MetaClass mc = MetaClassLoader.findMetaClass( obj );
    List<Object> list = getObjectsFromTable( c, mc );

    int i = list.indexOf( obj );
    if ( i < 0 )
      throw new MetaException( "Object [" + obj + "] did not exist in table for class [" + mc + "]" );

    if ( !isDeleteableClass( mc ))
      throw new MetaException( "Object of class [" + mc + "] is not persistable" );

    prePersistence( c, mc, obj, DELETE );

    list.remove( i );

    postPersistence( c, mc, obj, DELETE );
  }


  /**
   * Stores the specified object by adding, updating, or deleting
   */
  public void storeObject( ObjectConnection c, Object obj )
    throws MetaException
    {
        StatefulMetaClass pmc = getStatefulMetaClass( obj );

        if ( pmc.isNew( obj )) createObject( c, obj );
        else if ( pmc.isDeleted( obj )) deleteObject( c, obj );
        else if ( pmc.isModified( obj )) updateObject( c, obj );
    }


    ///////////////////////////////////////////////////////
    // PRIVATE METHODS
    //

    @SuppressWarnings("unchecked")
  private synchronized List<Object> getObjectsFromTable( ObjectConnection c, MetaClass mc )
        throws MetaException
    {
        Map<MetaClass,List<Object>> map = (Map<MetaClass,List<Object>>) c.getDatastoreConnection();

        ArrayList<Object> tmp = (ArrayList<Object>) map.get( mc );
        if ( tmp == null )
        {
            if ( isReadableClass( mc ))
                return loadObjectsFromFile( c, mc );

            tmp = new ArrayList<Object>();
            map.put( mc, tmp );
        }

        return tmp;
    }

    protected String getFileRef( MetaClass mc )
    {
        try {
            return (String) mc.getAttribute( "fileRef" );
        }
        catch( MetaAttributeNotFoundException e ) { }

        return mc.getShortName() + ".xml";
    }

    protected String getNameRef( MetaClass mc )
    {
        try {
            return (String) mc.getAttribute( "nameRef" );
        }
        catch( MetaAttributeNotFoundException e ) { }

        return mc.getShortName();
    }

    protected String getFieldRef( MetaField mf )
    {
        try {
            return (String) mf.getAttribute( "nameRef" );
        }
        catch( MetaAttributeNotFoundException e ) { }

        return mf.getName();
    }

    private InputStream getSourceStream( MetaClass mc )
        throws MetaException
    {
        String file = "";
        if ( getLocation() != null ) file += getLocation();
        file = file + getFileRef( mc );

        InputStream is = getClass().getClassLoader().getResourceAsStream( file );
        if ( is == null )
        {
            log.error( "Meta XML file [" + file + "] does not exist" );
            throw new MetaException( "The Meta XML item file [" + file + "] was not found" );
        }

        return is;
    }

    @SuppressWarnings("unchecked")
  private List<Object> loadObjectsFromFile( ObjectConnection c, MetaClass mc )
        throws MetaException
    {
        ///////////////////////////////////////////////////////////
        // Load the XML document
        Document doc = null;

        Map<MetaClass,List<Object>> map = (Map<MetaClass,List<Object>>) c.getDatastoreConnection();

        InputStream is = null;
        try {
          is = getSourceStream( mc );
          doc = XMLFileReader.loadFromStream( is );
        }
        catch( IOException e )
        {
          log.error( "Meta XML file for MetaClass [" + mc + "] cannot be parsed: " + e.getMessage() );
          throw new MetaException( "The Meta XML file for MetaClass [" + mc + "] was not parsable", e );
        }
        finally {
          try { if ( is != null ) is.close(); }
          catch( IOException e ) {}
        }

        /////////////////////////////////////////////////////
        // Parse the XML

        try
        {
            // Look for the <items> element
            NodeList itemdocList = doc.getElementsByTagName( "objects" );
            if ( itemdocList == null || itemdocList.getLength() == 0 )
                throw new MetaException( "The root 'objects' element was not found" );

            Element itemdocElement = (Element) itemdocList.item( 0 );

            Collection objects = parseObjects( c, mc, itemdocElement );

            List<Object> tmp = new ArrayList<Object>();

            // Place the resulting objects into the map
            for( Iterator i = objects.iterator(); i.hasNext(); )
                tmp.add( i.next() );

            // Add the objects to the map
            map.put( mc, tmp );

            return tmp;
        }
        catch( SAXException e )
        {
            throw new MetaException( "Unable to load Objects for MetaClass [" + mc + "]", e );
        }
    }

    private List<Object> parseObjects( ObjectConnection c, MetaClass mc, Element element )
        throws MetaException, SAXException
    {
        String nameRef = getNameRef( mc );

        NodeList objectList = element.getElementsByTagName( nameRef );
        List<Object> objects = new ArrayList<Object>();

        for( int i = 0; i < objectList.getLength(); i++ )
        {
            Element e = (Element) objectList.item( i );

            Object o = getNewObject( mc );

            for( MetaField mf : getReadableFields( mc ))
            {
                String fieldRef = getFieldRef( mf );

                NodeList list = e.getElementsByTagName( fieldRef );

                if ( list.getLength() > 0 )
                {
                    Element fe = (Element) list.item( 0 );
                    String value = "";
                    Node nv = fe.getFirstChild();
                    if ( nv != null ) value = nv.getNodeValue();

                    mf.setString( o, value );
                }
                else
                    mf.setString( o, null );
            }

            if ( mc instanceof StatefulMetaClass )
            {
                // It was pulled from the database, so it doesn't need to be flagged as modified
                ((StatefulMetaClass) mc ).setModified( o, false );

                // It is also no longer a new item
                ((StatefulMetaClass) mc ).setNew( o, false );
            }

            // Add the object to the returned vector
            objects.add( o );
        }

        return objects;
    }


    ///////////////////////////////////////////////////////
    // OBJECT QUERY LANGUAGE METHODS
    //

    public int execute( ObjectConnection c, String query, Collection<?> arguments ) throws MetaException
    {
      throw new UnsupportedOperationException( "execute is not support by the XML manager" );
    }

    public Collection<?> executeQuery( ObjectConnection c, String query, Collection<?> arguments ) throws MetaException
    {
      throw new UnsupportedOperationException( "executeQuery is not support by the XML manager" );
    }


    ///////////////////////////////////////////////////////
    // TO STRING METHOD
    //

    public String toString()
    {
        return "MetaManXML";
    }
}
TOP

Related Classes of com.draagon.meta.manager.xml.ObjectManagerXML

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.