您的位置:首页 > 其它

About Relation

2012-04-13 14:54 76 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/standyxu/article/details/84185676

org.structr.common.error  各种错误处理

 

/**
* Defines a class of relations between a source class and a target class with a direction and a cardinality.
*/
public class RelationClass
{

public static final int DELETE_BOTH = 3;
public static final int DELETE_INCOMING = 2;
public static final int DELETE_NONE = 0;
public static final int DELETE_OUTGOING = 1;
private static final Logger logger = Logger.getLogger(RelationClass.class.getName());

//~--- fields ---------------------------------------------------------

private Cardinality cardinality = null;
private Class destType = null;
private Direction direction = null;
private Notion notion = null;
private RelationshipType relType = null;
private int cascadeDelete = DELETE_NONE;

//~--- constant enums -------------------------------------------------

public enum Cardinality
{
OneToOne, OneToMany, ManyToOne, ManyToMany
}

//~--- constructors ---------------------------------------------------

public RelationClass(Class destType, RelationshipType relType, Direction direction, Cardinality cardinality, Notion notion, int cascadeDelete)
{

this.cascadeDelete = cascadeDelete;
this.cardinality = cardinality;
this.direction = direction;
this.destType = destType;
this.relType = relType;
this.notion = notion;
}

//~--- methods --------------------------------------------------------

public void createRelationship(final SecurityContext securityContext, final AbstractNode sourceNode, final Object value) throws FrameworkException
{
createRelationship(securityContext, sourceNode, value, Collections.EMPTY_MAP);
}

public void createRelationship(final SecurityContext securityContext, final AbstractNode sourceNode, final Object value, final Map properties) throws FrameworkException
{

// create relationship if it does not already exist
final Command createRel = Services.command(securityContext, CreateRelationshipCommand.class);
final Command deleteRel = Services.command(securityContext, DeleteRelationshipCommand.class);
AbstractNode targetNode;

if (value instanceof AbstractNode)
{

targetNode = (AbstractNode) value;

}
else
{

targetNode = (AbstractNode) Services.command(securityContext, FindNodeCommand.class).execute(value);

}

if ((sourceNode != null) && (targetNode != null))
{

final AbstractNode finalTargetNode = targetNode;
StructrTransaction transaction = new StructrTransaction()
{

@Override
public Object execute() throws FrameworkException
{

switch (cardinality)
{

case ManyToOne:
case OneToOne:
{

String destType = finalTargetNode.getType();

// delete previous relationships to nodes of the same destination type and direction
List<AbstractRelationship> rels = sourceNode.getRelationships(relType, direction);

for (AbstractRelationship rel : rels)
{

if (rel.getOtherNode(sourceNode).getType().equals(destType))
{

deleteRel.execute(rel);

}

}

break;

}

case OneToMany:
{

// Here, we have a OneToMany with OUTGOING Rel, so we need to remove all relationships
// of the same type incoming to the target node
List<AbstractRelationship> rels = finalTargetNode.getRelationships(relType, Direction.INCOMING);

for (AbstractRelationship rel : rels)
{

if (rel.getOtherNode(finalTargetNode).getType().equals(sourceNode.getType()))
{

deleteRel.execute(rel);

}

}
}

}

AbstractRelationship newRel;

if (direction.equals(Direction.OUTGOING))
{

newRel = (AbstractRelationship) createRel.execute(sourceNode, finalTargetNode, relType);

}
else
{

newRel = (AbstractRelationship) createRel.execute(finalTargetNode, sourceNode, relType);

}

newRel.setProperties(properties);

// set cascade delete value
if (cascadeDelete > 0)
{

newRel.setProperty(AbstractRelationship.HiddenKey.cascadeDelete, cascadeDelete);

}

return newRel;
}
};

// execute transaction
Services.command(securityContext, TransactionCommand.class).execute(transaction);

}
else
{

String type = "unknown";

if (sourceNode != null)
{

type = sourceNode.getType();

}
else if (targetNode != null)
{

type = targetNode.getType();

}

throw new FrameworkException(type, new IdNotFoundToken(value));

}
}

public void removeRelationship(final SecurityContext securityContext, final AbstractNode sourceNode, final Object value) throws FrameworkException
{

final Command deleteRel = Services.command(securityContext, DeleteRelationshipCommand.class);
AbstractNode targetNode = null;

if (value instanceof AbstractNode)
{

targetNode = (AbstractNode) value;

}
else
{

targetNode = (AbstractNode) Services.command(securityContext, FindNodeCommand.class).execute(value);

}

if ((sourceNode != null) && (targetNode != null))
{

final AbstractNode finalTargetNode = targetNode;
StructrTransaction transaction = new StructrTransaction()
{

@Override
public Object execute() throws FrameworkException
{

switch (cardinality)
{

case ManyToOne:
case OneToOne:
{

String destType = finalTargetNode.getType();

// delete previous relationships to nodes of the same destination type and direction
List<AbstractRelationship> rels = sourceNode.getRelationships(relType, direction);

for (AbstractRelationship rel : rels)
{

if (rel.getOtherNode(sourceNode).getType().equals(destType))
{

3ff7
deleteRel.execute(rel);

}

}

break;

}

case OneToMany:
{

// Here, we have a OneToMany with OUTGOING Rel, so we need to remove all relationships
// of the same type incoming to the target node
List<AbstractRelationship> rels = finalTargetNode.getRelationships(relType, Direction.INCOMING);

for (AbstractRelationship rel : rels)
{

if (rel.getOtherNode(finalTargetNode).getType().equals(sourceNode.getType()))
{

deleteRel.execute(rel);

}

}
}

case ManyToMany:
{

// In this case, remove exact the relationship of the given type
// between source and target node
List<AbstractRelationship> rels = finalTargetNode.getRelationships(relType, Direction.BOTH);

for (AbstractRelationship rel : rels)
{

if (rel.getOtherNode(finalTargetNode).equals(sourceNode))
{

deleteRel.execute(rel);

}

}
}

}

return null;
}
};

// execute transaction
Services.command(securityContext, TransactionCommand.class).execute(transaction);

}
else
{

String type = "unknown";

if (sourceNode != null)
{

type = sourceNode.getType();

}
else if (targetNode != null)
{

type = targetNode.getType();

}

throw new FrameworkException(type, new IdNotFoundToken(value));

}
}

public AbstractNode addRelatedNode(final SecurityContext securityContext, final AbstractNode node) throws FrameworkException
{

return (AbstractNode) Services.command(securityContext, TransactionCommand.class).execute(new StructrTransaction()
{

@Override
public Object execute() throws FrameworkException
{

AbstractNode relatedNode = (AbstractNode) Services.command(securityContext,
CreateNodeCommand.class).execute(new NodeAttribute(AbstractNode.Key.type.name(), getDestType().getSimpleName()));

// Create new relationship between facility and location nodes
Command createRel = Services.command(securityContext, CreateRelationshipCommand.class);
AbstractRelationship newRel = (AbstractRelationship) createRel.execute(node, relatedNode, getRelType());

if (cascadeDelete > 0)
{

newRel.setProperty(AbstractRelationship.HiddenKey.cascadeDelete, cascadeDelete);

}

return relatedNode;
}

});
}

//~--- get methods ----------------------------------------------------

public Class getDestType()
{
return destType;
}

public Direction getDirection()
{
return direction;
}

public Cardinality getCardinality()
{
return cardinality;
}

public RelationshipType getRelType()
{
return relType;
}

public Notion getNotion()
{
return notion;
}

// ----- public methods -----
public List<AbstractNode> getRelatedNodes(final SecurityContext securityContext, final AbstractNode node)
{

if (cardinality.equals(Cardinality.OneToMany) || cardinality.equals(Cardinality.ManyToMany))
{

// return getTraversalResults(securityContext, node, StringUtils.toCamelCase(type));
return getTraversalResults(securityContext, node);
}
else
{

logger.log(Level.WARNING, "Requested related nodes with wrong cardinality {0} between {1} and {2}", new Object[]{cardinality.name(), node.getClass().getSimpleName(),
destType});

}

return null;
}

public AbstractNode getRelatedNode(final SecurityContext securityContext, final AbstractNode node)
{

if (cardinality.equals(Cardinality.OneToOne) || cardinality.equals(Cardinality.ManyToOne))
{

List<AbstractNode> nodes = getTraversalResults(securityContext, node);

if ((nodes != null) && nodes.iterator().hasNext())
{

return nodes.iterator().next();

}

}
else
{

logger.log(Level.WARNING, "Requested related node with wrong cardinality {0} between {1} and {2}", new Object[]{cardinality.name(), node.getClass().getSimpleName(),
destType});

}

return null;
}

// ----- private methods -----
private List<AbstractNode> getTraversalResults(final SecurityContext securityContext, final AbstractNode node)
{

// final Class realType              = (Class) Services.command(securityContext, GetEntityClassCommand.class).execute(StringUtils.capitalize(destType));
final NodeFactory nodeFactory = new NodeFactory<AbstractNode>(securityContext);
final List<AbstractNode> nodeList = new LinkedList<AbstractNode>();

// use traverser
Iterable<Node> nodes = Traversal.description().uniqueness(Uniqueness.NODE_PATH).breadthFirst().relationships(relType, direction).evaluator(new Evaluator()
{

@Override
public Evaluation evaluate(Path path)
{

int len = path.length();

if (len <= 1)
{

if (len == 0)
{

// do not include start node (which is the
// index node in this case), but continue
// traversal
return Evaluation.EXCLUDE_AND_CONTINUE;
}
else
{

try
{

AbstractNode abstractNode = (AbstractNode) nodeFactory.createNode(securityContext, path.endNode());

// use inheritance
if ((destType != null) && destType.isAssignableFrom(abstractNode.getClass()))
{

nodeList.add(abstractNode);

return Evaluation.INCLUDE_AND_CONTINUE;

}
else
{

return Evaluation.EXCLUDE_AND_CONTINUE;

}

}
catch (FrameworkException fex)
{
logger.log(Level.WARNING, "Unable to instantiate node", fex);
}

}

}

return Evaluation.EXCLUDE_AND_PRUNE;
}

}).traverse(node.getNode()).nodes();

// iterate nodes to evaluate traversal
for (Node n : nodes)
{
}

return nodeList;
}

//~--- set methods ----------------------------------------------------

public void setDestType(Class destType)
{
this.destType = destType;
}

public void setDirection(Direction direction)
{
this.direction = direction;
}

public void setCardinality(Cardinality cardinality)
{
this.cardinality = cardinality;
}

public void setRelType(RelationshipType relType)
{
this.relType = relType;
}

public void setNotion(Notion notion)
{
this.notion = notion;
}
}

 

 

 

/**
* Describes a relation type between two node classes,
* defined by source and destination type (node entity classes) and the
* relationship type.
* <p/>
* Direction is always OUTGOING from source to destination by definition.
* <p/>
* A @see RelationshipMapping is marked with a combined key with name "type" of the form
* "SourceType RELTYPE DestType".
*/
public class RelationshipMapping
{

private static final Logger logger = Logger.getLogger(RelationshipMapping.class.getName());

//~--- fields ---------------------------------------------------------

private Class destType = null;
private String name = null;
private RelationshipType relType = null;
private Class sourceType = null;

//~--- constructors ---------------------------------------------------

public RelationshipMapping(String name, Class sourceType, Class destType, RelationshipType relType)
{

this.sourceType = sourceType;
this.destType = destType;
this.relType = relType;
this.name = name;
}

//~--- methods --------------------------------------------------------

public AbstractRelationship newEntityClass()
{

AbstractRelationship rel = null;
Class type = getEntityClass();

try
{
rel = (AbstractRelationship) type.newInstance();
}
catch (Throwable t)
{
logger.log(Level.WARNING, "Unable to instantiate relationship entity class", t);
}

return rel;
}

//~--- get methods ----------------------------------------------------

public RelationshipType getRelType()
{
return relType;
}

public Class getSourceType()
{
return sourceType;
}

public Class getDestType()
{
return destType;
}

public String getName()
{
return name;
}

public Class getEntityClass()
{
return EntityContext.getNamedRelationClass(sourceType.getSimpleName(), destType.getSimpleName(), relType.name());
}

public List<AbstractRelationship> getRelationships(AbstractNode obj) throws FrameworkException
{

Class combinedRelType = getEntityClass();
List<AbstractRelationship> relsFilteredByType = new LinkedList<AbstractRelationship>();

if (!(obj instanceof AbstractNode))
{

logger.log(Level.SEVERE, "Requested relationships of a non-node object");

throw new FrameworkException(HttpServletResponse.SC_BAD_REQUEST, new ErrorBuffer());

}

AbstractNode node = (AbstractNode) obj;

// filter relationships for correct combined relationship type
for (AbstractRelationship rel : node.getRelationships(relType, getDirectionForType(obj.getStringProperty(AbstractNode.Key.type.name()))))
{

if (rel.getClass().equals(combinedRelType))
{

relsFilteredByType.add(rel);

}

}

return relsFilteredByType;
}

// ----- private methods -----
private Direction getDirectionForType(String type) throws FrameworkException
{

if (type.equals(sourceType.getSimpleName()))
{

return Direction.OUTGOING;

}

if (type.equals(destType.getSimpleName()))
{

return Direction.INCOMING;

}

throw new FrameworkException(HttpServletResponse.SC_BAD_REQUEST, new ErrorBuffer());
}

//~--- set methods ----------------------------------------------------

public void setRelType(RelationshipType relType)
{
this.relType = relType;
}

public void setSourceType(Class sourceType)
{
this.sourceType = sourceType;
}

public void setDestType(Class destType)
{
this.destType = destType;
}

public void setName(String name)
{
this.name = name;
}
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: