Package anvil.server.db

Source Code of anvil.server.db.DBEntity

/*
* $Id: DBEntity.java,v 1.3 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Permission;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import anvil.core.Any;
import anvil.core.Serialization;
import anvil.core.UnserializationException;
import anvil.java.util.BindingEnumeration;
import anvil.java.util.Hashlist;
import anvil.java.security.PermissionCollectionCombiner;
import anvil.server.Zone;
import anvil.server.Realm;
import anvil.server.Tribe;
import anvil.server.Citizen;
import anvil.server.Realm;
import anvil.server.Tribe;
import anvil.server.Citizen;
import anvil.server.OperationFailedException;
import anvil.server.RealmPreferences;
import anvil.server.PolicyPreferences;

public abstract class DBEntity
{
  protected static final int E_REMOVED           = 1;
  protected static final int E_RESTORED          = 2;
  protected static final int E_COMBINED          = 4;
  protected static final int E_DIRTY_ATTRIBUTES  = 8;
  protected static final int E_DIRTY_PERMISSIONS = 16;
  protected static final int E_DIRTY             = E_DIRTY_ATTRIBUTES | E_DIRTY_PERMISSIONS;

  protected DBRealm _realm;
  protected int     _id;
  protected String  _name;
  protected byte    _flags = 0;
 
  protected LinkList              _parents     = new LinkList();
  protected PermissionCollection  _collection  = null;
  protected PermissionCollection  _combined    = null;
  protected ArrayList             _permissions = new ArrayList();
  protected Hashlist              _attributes  = null;

  /*package*/ DBEntity(DBRealm realm, int id)
  {
    _realm = realm;
    _id = id;
  }
 
/*package*/ DBEntity(DBRealm realm, int id, String name)
  {
    _realm = realm;
    _id = id;
    _name = name;
  }
   
 
  protected void check()
  {
    if ((_flags & E_REMOVED) != 0) {
      throw new IllegalStateException(this + " is removed");
    }
    if ((_flags & E_RESTORED) == 0) {
      _flags |= E_RESTORED;
      try {
        restore();
      } catch (OperationFailedException e) {
        _realm.log().error(e);
        throw new RuntimeException(e.toString());
      }
    }
  }

 
  protected void removed()
  {
    _flags |= E_REMOVED;
  }
 
 
  protected void dirty(int mask)
  {
    _flags |= mask;
  }
 


  public int hashCode()
  {
    return _id;
  }
 

  public boolean equals(Object o)
  {
    if (o instanceof DBEntity) {
      return _id == ((DBEntity)o)._id;
    }
    return false;
  }


  public Realm getRealm()
  {
    return _realm;
  }


  protected abstract String getType();
 

  /*package*/ int getId()
  {
    return _id;
  }

 
  public String getName()
  {
    return _name;
 

 
  /*package*/ synchronized void setName(String name)
  {
    check();
    _name = name;
  }
 
 
  protected String getCredentials()
  {
    return null;
  }


  public synchronized Tribe[] getParents()
  {
    check();
    return (Tribe[]) _parents.toArray(Tribe.class);
  }


  public synchronized void addPermission(Permission perm)
  {
    dirty(E_DIRTY_PERMISSIONS);
    _permissions.add(perm);
  }
 

  protected void addInitialPermission(Permission perm)
  {
    _permissions.add(perm);
    if (_collection == null) {
      _collection = new Permissions();
    }
    _collection.add(perm);
  }
 

  public synchronized void removePermission(Permission perm)
  {
    check();
    dirty(E_DIRTY_PERMISSIONS);
    _permissions.remove(perm);
  }


  public synchronized Iterator listPermissions()
  {
    check();
    return _permissions.iterator();
  }

 
  public synchronized PermissionCollection getPermissions()
  {
    check();
    return _collection;
  }


  private void getCombinedPermissions0(PermissionCollectionCombiner combiner,
    DBEntity entity)
  {
    combiner.combine(entity.getPermissions());
    Tribe[] tribes = entity.getParents();
    int n = tribes.length;
    for(int i=0; i<n; i++) {
      getCombinedPermissions0(combiner, (DBEntity)tribes[i]);
    }
  }

  public synchronized PermissionCollection getCombinedPermissions()
  {
    check();
    if ((_flags & E_COMBINED)==0) {
      _flags |= E_COMBINED;
      PermissionCollectionCombiner combiner = new PermissionCollectionCombiner();
      getCombinedPermissions0(combiner, this);
      _combined = combiner.getResult();
    }
    return _combined;
  }



  public synchronized BindingEnumeration getVariables()
  {
    check();
    if (_attributes == null) {
     
      return BindingEnumeration.EMPTY;
    } else {
      return _attributes.keysAndElements();
    }
  }
 
 

  public synchronized Any getVariable(String name)
  {
    check();
    if (_attributes == null) {
      return null;
    }
    return (Any)_attributes.get(name);
  }

 
  public synchronized Any setVariable(String name, Any value)
  {
    check();
    if (_attributes == null) {
      _attributes = new Hashlist();
    }
    dirty(E_DIRTY_ATTRIBUTES);
    _attributes.put(name, value);
    return value;
  }

 
  protected Any setInitialVariable(String name, Any value)
  {
    if (_attributes == null) {
      _attributes = new Hashlist();
    }
    _attributes.put(name, value);
    return value;
  }
 
 
  public synchronized Any checkVariable(String name)
  {
    check();
    if (_attributes == null) {
      return null;
    }
    return (Any)_attributes.get(name);
  }


  public synchronized boolean deleteVariable(String name)
  {
    check();
    if (_attributes == null) {
      return false;
    }
    if (_attributes.remove(name) != null) {
      dirty(E_DIRTY_ATTRIBUTES);
      return true;
    }
    return false;
  }
 
 
 
 
  public synchronized void commit() throws OperationFailedException
  {
    if ((_flags & E_DIRTY) == 0) {
      return;
    }
    check();
    _realm.perform(new Action() {
      public Object perform(Connection conn) throws OperationFailedException, SQLException
      {
        boolean attrsDirty = (_flags & E_DIRTY_ATTRIBUTES) != 0;
        boolean permissionsDirty = (_flags & E_DIRTY_PERMISSIONS) != 0;

       
        /*remove permissions and attributes */ {
          Statement stmt = null;
          try {
            stmt = conn.createStatement();
            if (permissionsDirty) {
              stmt.execute("delete from permission where id="+_id);
            }
            if (attrsDirty) {
              stmt.execute("delete from attribute where id="+_id);
            }
          } finally {
            close(stmt);
         
        }

        /* add permissions */
        if (permissionsDirty && _permissions != null) {
          PreparedStatement stmt = null;
          try {
            stmt = conn.prepareStatement("insert into permission values(?,?,?,?)");
            int n = _permissions.size();
            for(int i=0; i<n; i++) {
              stmt.clearParameters();
              stmt.setInt(1, _id);
              Permission perm = (Permission)_permissions.get(i);
              stmt.setString(2, perm.getClass().getName());
              stmt.setString(3, perm.getName());
              stmt.setString(4, perm.getActions());
              stmt.execute();
            }
          } finally {
            close(stmt);
          }
        }

        /* add attributes */
        if (attrsDirty) {
          storeAttributes(conn);
        }
       
        return null;
      }
    });
  }

  protected void storeAttributes(Connection conn) throws OperationFailedException, SQLException
  {
    if (_attributes != null) {
      PreparedStatement stmt = null;
      try {
        stmt = conn.prepareStatement("insert into attribute values(?,?,?,?,?)");
        BindingEnumeration enum = _attributes.keysAndElements();
        for(int i=0; enum.hasMoreElements(); i++) {
          stmt.clearParameters();
          String name = (String)enum.nextKey();
          Any value = (Any)enum.nextElement();
          stmt.setInt(1, _id);
          stmt.setInt(2, i);
          stmt.setString(3, name);
          if(value.isString()) {
            stmt.setInt(4, 1);
            stmt.setString(5, value.toString());
          } else {
            stmt.setInt(4, 0);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            try {
              Serialization.serialize(null, value, output);
            } catch (IOException e) {
              throw new OperationFailedException(
                "Serizalition of type '"+value.classOf()+"' failed");
            }
            stmt.setBytes(5, output.toByteArray());
          }
          stmt.execute();
        }
      } finally {
        Action.close(stmt);
      }
    }
  }

  public synchronized void remove() throws OperationFailedException
  {
    check();
    synchronized(_realm) {
      _realm.perform(new Action() {
        public Object perform(Connection conn) throws SQLException
        {
          Statement stmt = conn.createStatement();
          try {
            stmt.executeQuery("delete from entity where id="+_id);
            stmt.executeQuery("delete from permission where id="+_id);
            stmt.executeQuery("delete from attribute where id="+_id);
            stmt.executeQuery("delete from relation where child="+_id+" or parent="+_id);
            return null;
          } finally {
            close(stmt);
          }
        }
      });
      removeRelations();
    }
   
    removed();
  }
 
 
  protected void removeRelations()
  {
    _parents.forEach(new LinkList.Action()
      {
        public void perform(Link link)
        {
          DBEntity entity = _realm.getCachedEntity(link.getId());
          if (entity != null) {
            entity.removeChild(DBEntity.this);
          }
        }
      }
    );
  }
 
 
  /*package*/ void create(final String[][] attrs) throws OperationFailedException
  {
    _realm.perform(
      new Action() {
        public Object perform(Connection conn) throws OperationFailedException, SQLException
        {
          PreparedStatement stmt = null;
          try {
            stmt = conn.prepareStatement("insert into entity values(?,?,?,?)");
            stmt.setInt(1, _id);
            stmt.setString(2, getType());
            stmt.setString(3, _name);
            stmt.setString(4, getCredentials());
            stmt.execute();
          } finally {
            close(stmt);
          }

          if (attrs != null) {         
            int n = attrs.length;
            for(int i=0; i<n; i++) {
              String[] s = attrs[i];
              setInitialVariable(s[0], Any.create(s[1]));
            }

            storeAttributes(conn);
          }
         
          return null;
        }
      }
    );   
  }


  /*package*/ void restore() throws OperationFailedException
  {
    _realm.perform(
      new Action() {
        public Object perform(Connection conn) throws OperationFailedException, SQLException
        {
          Statement stmt = null;
          ResultSet set = null;
          try {
            stmt = conn.createStatement();
            set = stmt.executeQuery("select * from permission where id="+_id);
            while(set.next()) {
              String type = set.getString(2);
              String name = set.getString(3);
              String actions = set.getString(4);
              try {
                Permission perm = PolicyPreferences.createPermission(
                  new String[] { type, name, actions });
                addInitialPermission(perm);
              } catch (Throwable t) {
                _realm.log().error(t);
                throw new OperationFailedException("Invalid permission: "+t.toString());
              }
            }
            close(set);

            set = stmt.executeQuery("select name, isstring, value from attribute where id="+_id);
            while(set.next()) {
              String name = set.getString(1);
              if (set.getInt(2) != 0) {
                setInitialVariable(name, Any.create(set.getString(3)));
              } else {
                byte[] data = set.getBytes(3);
                try {
                  Any value = Serialization.unserialize(null, data, 0, data.length);
                  setInitialVariable(name, value);
                } catch (UnserializationException t) {
                  throw new OperationFailedException("Invalid permission: "+t.toString());
                }
              }
            }
            close(set);
           
            set = stmt.executeQuery("select parent, child, type from relation where parent="+_id+" or child="+_id);
            while(set.next()) {
              restoreRelation(set.getInt(1), set.getInt(2), set.getString(3).equals("t"));
            }

            return null;
          } finally {
            close(set);
            close(stmt);
          }
        }
      }
    );

  }
 
  protected void restoreRelation(int parent, int child, boolean childIsTribe)
  {
    if (child == _id) {
      _parents.add(new TribeLink(_realm, parent));
    }
  }
 
  protected void addParent(DBTribe parent)
  {
    _parents.add(new TribeLink(_realm, parent.getId()));
  }


  protected void removeParent(DBTribe parent)
  {
    _parents.remove(parent.getId());
  }


  protected void removeChild(DBEntity child)
  {
  }
       
 
}

TOP

Related Classes of anvil.server.db.DBEntity

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.