Package org.dmd.dmp.server.extended

Source Code of org.dmd.dmp.server.extended.DMPEvent

//  ---------------------------------------------------------------------------
//  dark-matter-data
//  Copyright (c) 2011 dark-matter-data committers
//  ---------------------------------------------------------------------------
//  This program is free software; you can redistribute it and/or modify it
//  under the terms of the GNU Lesser General Public License as published by the
//  Free Software Foundation; either version 3 of the License, or (at your
//  option) any later version.
//  This program is distributed in the hope that it will be useful, but WITHOUT
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
//  more details.
//  You should have received a copy of the GNU Lesser General Public License along
//  with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
//  ---------------------------------------------------------------------------
package org.dmd.dmp.server.extended;

import java.util.Iterator;

import org.dmd.dmc.DmcAttribute;
import org.dmd.dmc.DmcAttributeInfo;
import org.dmd.dmc.DmcNamedObjectIF;
import org.dmd.dmc.DmcObject;
import org.dmd.dmc.DmcObjectName;
import org.dmd.dmc.DmcOmni;
import org.dmd.dmc.DmcSliceInfo;
import org.dmd.dmc.DmcValueException;
import org.dmd.dmc.types.Modifier;
import org.dmd.dmp.server.generated.dmw.DMPEventDMW;
import org.dmd.dmp.shared.generated.dmo.DMPEventDMO;
import org.dmd.dmp.shared.generated.enums.DMPEventTypeEnum;
import org.dmd.dms.AttributeDefinition;
import org.dmd.dms.generated.dmo.MetaDMSAG;
import org.dmd.dms.generated.enums.DataTypeEnum;
import org.dmd.dms.generated.enums.ModifyTypeEnum;
import org.dmd.dms.generated.types.DmcTypeModifierMV;
import org.dmd.dmw.DmwOmni;
import org.dmd.dmw.DmwWrapper;

public class DMPEvent extends DMPEventDMW {

  public DMPEvent(){
    super();
  }
 
  public DMPEvent(DMPEventDMO obj){
    super(obj);
  }
 
  public DMPEvent(DMPEventTypeEnum et, DmwWrapper w){
    super();
    setEventTypeDMP(et);
    setSourceObjectClass(w.getConstructionClass());
    if (w instanceof DmcNamedObjectIF){
      DmcObjectName on = ((DmcNamedObjectIF)w).getObjectName();
      if (on != null)
        setSource(on);
    }
   
    if (et == DMPEventTypeEnum.CREATED){
      setSourceObject(w.getDmcObject());
    }
    else if (et == DMPEventTypeEnum.LOADED){
      setSourceObject(w.getDmcObject());
    }
    else if (et == DMPEventTypeEnum.DELETED){
      if (w instanceof DmcNamedObjectIF){
        DmcObjectName on = ((DmcNamedObjectIF)w).getObjectName();
        if (on != null)
          setSource(on);
      }
    }
    else if (et == DMPEventTypeEnum.MODIFIED){
      if (w.getModifier() == null)
        throw(new IllegalStateException("Tried to create a MODIFIED event for an object with no modifications."));
     
      // Only add the modifier if there's something in it
      if (w.getModifier().getMVSize() > 0)
        setModify(w.getModifier());
    }
  }
 
  /**
   * Returns a clone of this DMPEvent.
   */
  public DMPEvent clone(){
    return(new DMPEvent((DMPEventDMO) this.getDMO().shallowCopy()));
  }
 
  /**
   * Checks to see if the event contains information about persistent objects/attributes.
   * A variety of checks are performed, depending on the type of the event.
   * <p />
   * If the source object class is not PERSISTENT, we return false.
   * <p />
   * If it's a CREATE event, we check to see if any of the attributes (beyond the objectClass)
   * are PERSISTENT, if so, we return true.
   * <p />
   * If it's a DELETE event, we return true.
   * <p />
   * If it's a MODIFIED event, we check the modify attribute. If it refers to any PERSISTENT
   * attribute, we return true.
   * @return true if there's persistent data and false otherwise.
   */
  public boolean hasPersistentData(){
    boolean rc = false;
   
   
    if (getSourceObjectClass() == null)
      throw(new IllegalStateException("Malformed DMPEvent. Missing source object class for a " + getEventTypeDMP() + " event."));
   
    if (getSourceObjectClass().getDataType() != DataTypeEnum.PERSISTENT)
      return(rc);

    if ( (getEventTypeDMP() == DMPEventTypeEnum.CREATED) || (getEventTypeDMP() == DMPEventTypeEnum.LOADED)){
      if (getSourceObject() == null)
        throw(new IllegalStateException("Malformed DMPEvent. Missing source object for a CREATE event."));
       
      for(DmcAttribute<?> attr: getSourceObject().getAttributes().values()){
        if (attr.getID() == DmcObject.__objectClass.id)
          continue;
        if (attr.getAttributeInfo().dataType == DataTypeEnum.PERSISTENT){
          rc = true;
          break;
        }
      }
    }
    else if (getEventTypeDMP() == DMPEventTypeEnum.DELETED){
      // The object is persistent and we only have the name, so go ahead
      rc = true;
    }
    else if (getEventTypeDMP() == DMPEventTypeEnum.MODIFIED){
      if (getModifyAttribute() == null)
        throw(new IllegalStateException("Malformed DMPEvent. Missing modify attribute for a MODIFIED event."));
     
      Iterator<Modifier>  modifiers = getModifyAttribute().getMV();
      if (modifiers != null){
        while(modifiers.hasNext()){
          Modifier mod = modifiers.next();
          if (mod.getAttribute() == null){
            if (mod.getModifyType() == ModifyTypeEnum.REM){
              AttributeDefinition ad = DmwOmni.instance().getSchema().adef(mod.getAttributeName());
              if (ad == null)
                throw(new IllegalStateException("Malformed DMPEvent. Could not get definition for attribute: " + mod.getAttributeName()));
              else
                if (ad.getDataType() == DataTypeEnum.PERSISTENT){
                  rc = true;
                  break;
                }
            }
            else if (mod.getModifyType() == ModifyTypeEnum.NTH){
              AttributeDefinition ad = DmwOmni.instance().getSchema().adef(mod.getAttributeName());
              if (ad == null)
                throw(new IllegalStateException("Malformed DMPEvent. Could not get definition for attribute: " + mod.getAttributeName()));
              else
                if (ad.getDataType() == DataTypeEnum.PERSISTENT){
                  rc = true;
                  break;
                }
            }
            else
              throw(new IllegalStateException("Malformed DMPEvent. Missing attribute for a Modifier: " + mod.toString()));
          }
          else if (mod.getAttribute().getAttributeInfo().dataType == DataTypeEnum.PERSISTENT){
            rc = true;
            break;
          }
        }
      }
     
    }
   
    return(rc);
  }
 
  /**
   * This method will return either, the current event (if all information is PERSISTENT)
   * or a trimmed down clone of the event with non-PERSISTENT information removed.
   * <p/>
   * If none of the data is PERSISTENT, null is returned.
   * <p />
   * If the source object class is not PERSISTENT, we return null.
   * <p />
   * If it's a CREATED/LOADED event, we check to see if any of the attributes are non-PERSISTENT,
   * if so, we strip those attributes from the source object and return a clone of the event
   * with the source object replaced with a new source object WITHOUT the non-PERSISTENT attributes.
   * <p />
   * If it's a DELETE event, we just return the event (since it only has the name of the object
   * being deleted).
   * <p />
   * If it's a MODIFIED event, we check the modify attribute. If it refers to any PERSISTENT
   * attribute, we return true.
   * @return a clone of the DMPEvent with only the PERSISTENT information and null if there's no
   * PERSISTENT data.
   */
  public DMPEvent getPersistentForm(){
    DMPEvent rc = null;
   
    if (getSourceObjectClass() == null)
      throw(new IllegalStateException("Malformed DMPEvent. Missing source object class for a " + getEventTypeDMP() + " event."));
   
    if (getSourceObjectClass().getDataType() != DataTypeEnum.PERSISTENT)
      return(rc);

    try {
      if ( (getEventTypeDMP() == DMPEventTypeEnum.CREATED) || (getEventTypeDMP() == DMPEventTypeEnum.LOADED)){
        if (getSourceObject() == null)
          throw(new IllegalStateException("Malformed DMPEvent. Missing source object for a CREATE event."));
       
        DmcObject clonedSourceObj = getSourceObject().getNew();
         
        int nonPersistentCount = 0;
        for(DmcAttribute<?> attr: getSourceObject().getAttributes().values()){
          if (attr.getID() == DmcObject.__objectClass.id)
            continue;
          if (attr.getAttributeInfo().dataType == DataTypeEnum.PERSISTENT){
            clonedSourceObj.add(attr.getAttributeInfo(), attr.cloneIt());
          }
          else
            nonPersistentCount++;
        }
       
        if (nonPersistentCount > 0){
          // If we stripped any non persistent attributes, replace the source object
          // with the new one.
          rc = clone();
          rc.remSourceObject();
          rc.setSourceObject(clonedSourceObj);
        }
        else{
          // We didn't modify anything, so just return teh event as is
          rc = this;
        }

      }
      else if (getEventTypeDMP() == DMPEventTypeEnum.DELETED){
        rc = this;
      }
      else if (getEventTypeDMP() == DMPEventTypeEnum.MODIFIED){
        if (getModifyAttribute() == null)
          throw(new IllegalStateException("Malformed DMPEvent. Missing modify attribute for a MODIFIED event."));
       
        // Create a new modifier collection to which we'll add the persistent
        // attribute modifications.
        DmcTypeModifierMV newModifier = new DmcTypeModifierMV(MetaDMSAG.__modify);
       
        Iterator<Modifier>  modifiers = getModifyAttribute().getMV();
        if (modifiers != null){
          while(modifiers.hasNext()){
            Modifier mod = modifiers.next();
            DmcAttributeInfo ai = mod.getAttributeInfo();
            if (ai == null)
              throw(new IllegalStateException("Unknown attribute in modify: " + mod.getAttributeName()));
            if (ai.dataType == DataTypeEnum.PERSISTENT)
              newModifier.add(new Modifier(mod));
          }
         
          // If there are any PERSISTENT modifications, we'll returned an alterred clone
          if (newModifier.getMVSize() > 0){
            // There were non-persistent attributes in the modify, clone the event
            // and replace the modify with alterred modify
            rc = clone();
            rc.remModify();
            rc.getDMO().add(MetaDMSAG.__modify, newModifier);
          }
        }
      }
    }
    catch(DmcValueException ex){
      throw(new IllegalStateException("Shouldn't have value exceptions for attribute: " + ex.getAttributeName() + "\n" + ex.toString()));
    }
   
    return(rc);
  }
 

 
  /**
   * A convenience constructor that creates a MODIFIED event based on the contents of
   * the SetRequest passed as argument. The source will be the target of the request.
   * @param request
   */
  public DMPEvent(SetRequest request){
    setEventTypeDMP(DMPEventTypeEnum.MODIFIED);
    setSource(request.getTarget());
   
    if (request.getTargetObjectClass() != null)
      setSourceObjectClass(request.getTargetObjectClass());
   
    if (request.getModifyAttribute() == null)
      throw(new IllegalStateException("Tried to create a MODIFIED event from a SetRequest with no modifications."));

    setModify(request.getModifyAttribute());
  }
 
  @Override
  public DmcTypeModifierMV getModifier(){
    throw(new IllegalStateException("It makes no sense to retrieve the modifier from an event - you probably meant getModify()."));
  }
 
  public DmcObjectName getSourceName(){
    if (getSource() == null)
      return(null);
   
    return(getSource().getName());
  }
 
  /**
   * A convenience function to set the modify attribute directly on the
   * underlying EventDMO object.
   * @param mods
   */
  public void setModify(DmcTypeModifierMV mods){
    try {
      getDmcObject().add(MetaDMSAG.__modify,mods);
    } catch (DmcValueException e) {
      throw(new IllegalStateException("Setting the modify attribute directly with a DmcTypeModifierMV shouldn't thrown an exception.",e));
    }
  }
 
  /**
   * A convenience method to directly access the modify attribute which must be
   * passed to the DmcObject.applyModifier() method.
   * @return The modify attribute.
   */
  public DmcTypeModifierMV getModifyAttribute(){
    return (DmcTypeModifierMV) (getDmcObject().get(MetaDMSAG.__modify));
  }
 
  /**
   * If the event object has generated/extended DMW code, this method will return the
   * DMO wrapped in its associated DMW object.
   * @return The wrapped DMO.
   */
  public DmwWrapper getSourceObjectWrapped(){
    if (getSourceObject() == null)
      return(null);
    return(DmwOmni.instance().wrapIt(getSourceObject()));
  }
 
  /**
   * @return The DmcSliceInfo if the slice is defined on this event.
   */
  public DmcSliceInfo getSliceInfo(){
    if (getSlice() == null)
      return(null);
   
    return(DmcOmni.instance().getSliceInfo(getSlice()));
  }

  /**
   * This method will slice the event appropriately, depending on the type of event and
   * the specified slice.
   * <P>
   * If this is a MODIFIED event, we will check to see if any of the attributes in the
   * modifier are associated with the specified slice. If so, a new DMPEvent is returned
   * that has the modifier sliced to contain only changes associated with the slice. If not,
   * null is returned.
   * <P>
   * If this is a CREATED/LOADED event, we slice the object for the required attributes and return
   * a new DMPEvent with that information. NOTE: we always return a new event, even if all
   * we have is the name of the object.
   * @param dsi
   * @return a sliced event with the appropriate attributes.
   */
  public DMPEvent getSlice(DmcSliceInfo dsi){
    DMPEvent rc = null;
   
    if (getEventTypeDMP() == DMPEventTypeEnum.MODIFIED){
      // Pull the modifier
      DmcTypeModifierMV source = getModifyAttribute();
     
      // Check if the modifier touches any of the attributes in the slice
      DmcTypeModifierMV sliced = getModifierSlice(dsi, source);
     
      // If we get a value back from getModifierSlice() it means that the sliced attributes were touched
      // Whether they were touched inappropriately remains to be seen!
      if (sliced != null){
        // We create a new DMPEvent which contains a shallow copy of the DMO - this is just a straight
        // populating of the attribute map with the original DMO's attributes
        rc = new DMPEvent((DMPEventDMO) this.getDMO().shallowCopy());
       
        rc.setSlice(dsi.getName());
       
        // We remove the original modify attribute - this doesn't harm the modify
        // in the original event
        rc.remModify();
       
        try {
          // And then we replace the modifier with our sliced modifier
          rc.getDMO().set(MetaDMSAG.__modify, sliced);
        } catch (DmcValueException e) {
          throw(new IllegalStateException("Dropping the sliced modifier in our shallow copy shouldn't throw an exception!"));
        }
      }
    }
    else if ( (getEventTypeDMP() == DMPEventTypeEnum.CREATED) || (getEventTypeDMP() == DMPEventTypeEnum.LOADED)){
      DmcObject sliced = getSourceObject().getSlice(dsi);
//      if (sliced.numberOfAttributes() > 1){
        // We have more than the objectClass attribute so create the new event
        rc = new DMPEvent((DMPEventDMO) this.getDMO().shallowCopy());
       
        rc.setSlice(dsi.getName());
       
        // Remove the original source object
        rc.remSourceObject();
       
        // Replace it with the sliced object
        rc.setSourceObject(sliced);
//      }
    }
    else if (getEventTypeDMP() == DMPEventTypeEnum.DELETED){
      // We clone the event because we have to tag it with a listenerID
      // when it's sent back
      rc = new DMPEvent((DMPEventDMO) this.getDMO().shallowCopy());
      rc.setSlice(dsi.getName());
    }
   
    return(rc);
  }
 
  /**
   * Determines if the specified source modifier contains any of the attributes in the specified slice.
   * @param slice the slice of attributes.
   * @param source the source modifier.
   * @return The modifier with the sliced attributes or null if none of the attributes matched.
   */
  DmcTypeModifierMV getModifierSlice(DmcSliceInfo slice, DmcTypeModifierMV source){
    DmcTypeModifierMV rc = new DmcTypeModifierMV();
   
    Iterator<Modifier> mods = source.getMV();
    while(mods.hasNext()){
      Modifier mod = mods.next();
      if (slice.contains(mod.getAttributeID())){
        try {
          rc.add(mod);
        } catch (DmcValueException e) {
          throw(new IllegalStateException("Should not throw an exception adding a Modifier to a DmcTypeModifier"));
        }
      }
    }
   
    if (rc.getMVSize() == 0)
      rc = null;
   
    return(rc);
  }
   
  /**
   * This convenience method can be used on MODIFIED events to determine whether
   * or not the specified attribute is alterred by the modifier.
   * @param ai
   * @return
   */
  public boolean thisAttributeModified(DmcAttributeInfo ai){
    if (getEventTypeDMP() == DMPEventTypeEnum.MODIFIED){
      DmcTypeModifierMV mods = getModifyAttribute();
      if (mods != null){
        for(int i=0; i<mods.getMVSize(); i++){
          Modifier mod = mods.getMVnth(i);
          DmcAttributeInfo modai = mod.getAttributeInfo();
          if (modai == null)
            throw(new IllegalStateException("Couldn't get attriute info for: " + mod.getAttributeName()));
          if (modai.id == ai.id)
            return(true);
        }
      }
    }
    return(false);
  }

}
TOP

Related Classes of org.dmd.dmp.server.extended.DMPEvent

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.