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; } }
相关文章推荐
- 安装完Ubuntu11.10后要做的10件事[Sudobits Blog]
- PHP面试题
- SUM+IF语句中使用逻辑函数AND和/或OR
- android环境搭建之旅-- (二)ubuntu与主机XP的共享
- 在Linux内核中单独编译KO文件
- Oracle 11.2.0.2 exp导出错误处理一则
- 如何理解C和C++的复杂类型声明
- c语言字符串函数详解
- 在ASP.net 3.5中 用JSON序列化对象(两种方法)
- 虚拟机 桥接,NAT,Host Only的区别(转)
- hash表的代码
- C++计算一元二次方程的跟
- Socket通信过程
- STL 应用之set
- Linux下搭建Haproxy负载均衡
- 常用正则验证
- Java类型转换
- 给easyui的menubutton添加hide方法
- vs2010如何检测内存泄漏
- linux下手工创建数据库,并用rman备份