Changeset 13:abe25edf2178 in AnnotationManagerN4J for src


Ignore:
Timestamp:
Jul 13, 2012, 3:22:05 PM (12 years ago)
Author:
casties
Branch:
default
Message:

storing and retrieving permissions works now.

Location:
src/main/java/de/mpiwg/itgroup/annotations
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/main/java/de/mpiwg/itgroup/annotations/Actor.java

    r10 r13  
    2727        return uri;
    2828    }
     29
     30    /**
     31     * Returns the uri (uses id if empty).
     32     *
     33     * @return the uri
     34     */
     35    public String getUriString() {
     36        if (uri == null) {
     37                return getUriFromId(id, isGroup());
     38        }
     39        return uri;
     40    }
     41
    2942    /**
    3043     * @param uri the uri to set
  • src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java

    r12 r13  
    3030public class AnnotationStore {
    3131
    32     protected static Logger logger = Logger.getLogger(AnnotationStore.class);
    33 
    34     protected GraphDatabaseService graphDb;
    35 
    36     public static enum NodeTypes {
    37         ANNOTATION, PERSON, TARGET
    38     }
    39 
    40     protected List<Index<Node>> nodeIndexes;
    41 
    42     public static enum RelationTypes implements RelationshipType {
    43         ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ
    44     }
    45 
    46     public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/";
    47 
    48     public AnnotationStore(GraphDatabaseService graphDb) {
    49         super();
    50         this.graphDb = graphDb;
    51         nodeIndexes = new ArrayList<Index<Node>>(3);
    52         // List.set(enum.ordinal(), val) seems not to work.
    53         nodeIndexes.add(NodeTypes.ANNOTATION.ordinal(), graphDb.index().forNodes("annotations"));
    54         nodeIndexes.add(NodeTypes.PERSON.ordinal(), graphDb.index().forNodes("persons"));
    55         nodeIndexes.add(NodeTypes.TARGET.ordinal(), graphDb.index().forNodes("targets"));
    56     }
    57 
    58     protected Index<Node> getNodeIndex(NodeTypes type) {
    59         return nodeIndexes.get(type.ordinal());
    60     }
    61 
    62     /**
    63      * Returns the Annotation with the given id.
    64      *
    65      * @param id
    66      * @return
    67      */
    68     public Annotation getAnnotationById(String id) {
    69         Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle();
    70         Annotation annot = createAnnotationFromNode(annotNode);
    71         return annot;
    72     }
    73 
    74     /**
    75      * Returns an Annotation object from an annotation-Node.
    76      *
    77      * @param annotNode
    78      * @return
    79      */
    80     public Annotation createAnnotationFromNode(Node annotNode) {
    81         Annotation annot = new Annotation();
    82         annot.setUri((String) annotNode.getProperty("id", null));
    83         annot.setBodyText((String) annotNode.getProperty("bodyText", null));
    84         annot.setBodyUri((String) annotNode.getProperty("bodyUri", null));
    85         // get annotation target from relation
    86         Relationship targetRel = getRelation(annotNode, RelationTypes.ANNOTATES, null);
    87         if (targetRel != null) {
    88             Node target = targetRel.getEndNode();
    89             annot.setTargetBaseUri((String) target.getProperty("uri", null));
    90         } else {
    91             logger.error("annotation "+annotNode+" has no target node!");
    92         }
    93         annot.setTargetFragment((String) annotNode.getProperty("targetFragment", null));
    94         String ft = (String) annotNode.getProperty("fragmentType", null);
    95         if (ft != null) {
    96             annot.setFragmentType(FragmentTypes.valueOf(ft));
    97         }
    98         // get creator from relation
    99         Relationship creatorRel = getRelation(annotNode, RelationTypes.CREATED, null);
    100         if (creatorRel != null) {
    101             Node creatorNode = creatorRel.getStartNode();
    102             Actor creator = createActorFromNode(creatorNode);
    103             annot.setCreator(creator);
    104         } else {
    105             logger.error("annotation "+annotNode+" has no creator node!");
    106         }
    107         // get creation date
    108         annot.setCreated((String) annotNode.getProperty("created", null));
    109         // get permissions
    110         Relationship adminRel = getRelation(annotNode, RelationTypes.PERMITS_ADMIN, null);
    111         if (adminRel != null) {
    112             Node adminNode = adminRel.getEndNode();
    113             //FIXME
    114         }
    115        
    116         return annot;
    117     }
    118 
    119     /**
    120      * Returns an Actor object from a node.
    121      *
    122      * @param actorNode
    123      * @return
    124      */
    125     protected Actor createActorFromNode(Node actorNode) {
    126         String uri = (String) actorNode.getProperty("uri", null);
    127         String name = (String) actorNode.getProperty("name", null);
    128         String type = (String) actorNode.getProperty("TYPE", null);
    129         Actor creator = null;
    130         if (type != null && type.equals("PERSON")) {
    131             creator = new Person(uri, name);
    132         } else if (type != null && type.equals("GROUP")) {
    133             creator = new Group(uri, name);
    134         }
    135         return creator;
    136     }
    137 
    138     /**
    139      * Store a new annotation in the store or update an existing one. Returns
    140      * the stored annotation.
    141      *
    142      * @param annot
    143      * @return
    144      */
    145     public Annotation storeAnnotation(Annotation annot) {
    146         Node annotNode = null;
    147         Transaction tx = graphDb.beginTx();
    148         try {
    149             /*
    150              * create or get the annotation
    151              */
    152             String id = annot.getUri();
    153             if (id == null) {
    154                 id = createRessourceURI("annot:");
    155             }
    156             annotNode = getOrCreateAnnotationNode(id);
    157 
    158             /*
    159              * the annotation body
    160              */
    161             String bodyText = annot.getBodyText();
    162             if (bodyText != null) {
    163                 annotNode.setProperty("bodyText", bodyText);
    164             }
    165             String bodyUri = annot.getBodyUri();
    166             if (bodyUri != null) {
    167                 annotNode.setProperty("bodyUri", bodyUri);
    168             }
    169 
    170             /*
    171              * the annotation target
    172              */
    173             String targetBaseUri = annot.getTargetBaseUri();
    174             if (targetBaseUri != null) {
    175                 Node target = getOrCreateTargetNode(targetBaseUri);
    176                 getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target);
    177             }
    178 
    179             /*
    180              * The fragment part of the annotation target.
    181              */
    182             String targetFragment = annot.getTargetFragment();
    183             FragmentTypes fragmentType = annot.getFragmentType();
    184             if (targetFragment != null) {
    185                 annotNode.setProperty("targetFragment", targetFragment);
    186                 annotNode.setProperty("fragmentType", fragmentType.name());
    187             }
    188 
    189             /*
    190              * The creator of this annotation.
    191              */
    192             Actor creator = annot.getCreator();
    193             if (creator != null) {
    194                 Node creatorNode = getOrCreatePersonNode(creator);
    195                 getOrCreateRelation(creatorNode, RelationTypes.CREATED, annotNode);
    196             }
    197 
    198             /*
    199              * The creation date of this annotation.
    200              */
    201             String created = annot.getCreated();
    202             if (created != null) {
    203                 annotNode.setProperty("created", created);
    204             }
    205 
    206             /*
    207              * Permissions for this annotation.
    208              */
    209             setPermissionRelation(annotNode, RelationTypes.PERMITS_ADMIN, annot.getAdminPermission());
    210             setPermissionRelation(annotNode, RelationTypes.PERMITS_DELETE, annot.getDeletePermission());
    211             setPermissionRelation(annotNode, RelationTypes.PERMITS_UPDATE, annot.getUpdatePermission());
    212             setPermissionRelation(annotNode, RelationTypes.PERMITS_READ, annot.getReadPermission());
    213 
    214             tx.success();
    215         } finally {
    216             tx.finish();
    217         }
    218 
    219         // re-read and return annotation
    220         Annotation storedAnnot = createAnnotationFromNode(annotNode);
    221         return storedAnnot;
    222     }
    223 
    224     /**
    225      * Deletes the annotation with the given id.
    226      *
    227      * @param id
    228      */
    229     public void deleteById(String id) {
    230         Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle();
    231         if (annotNode != null) {
    232             // delete related objects
    233             Transaction tx = graphDb.beginTx();
    234             try {
    235                 for (Relationship rel : annotNode.getRelationships()) {
    236                     // delete relation and the related node if it has no other
    237                     // relations
    238                     Node other = rel.getOtherNode(annotNode);
    239                     rel.delete();
    240                     if (!other.hasRelationship()) {
    241                         deleteNode(other);
    242                     }
    243                 }
    244                 if (!annotNode.hasRelationship()) {
    245                     deleteNode(annotNode);
    246                 } else {
    247                     logger.error("deleteById: unable to delete: Node still has relations.");
    248                 }
    249                 tx.success();
    250             } finally {
    251                 tx.finish();
    252             }
    253         }
    254     }
    255 
    256     /**
    257      * Returns all annotations with the given uri and/or user.
    258      *
    259      * @param uri
    260      * @param userUri
    261      * @param limit
    262      * @param offset
    263      * @return
    264      */
    265     public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) {
    266         List<Annotation> annotations = new ArrayList<Annotation>();
    267         if (targetUri != null) {
    268             // there should be only one
    269             Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri).getSingle();
    270             if (target != null) {
    271                 Iterable<Relationship> relations = target.getRelationships(RelationTypes.ANNOTATES);
    272                 for (Relationship relation : relations) {
    273                     Node ann = relation.getStartNode();
    274                     if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
    275                         Annotation annot = createAnnotationFromNode(ann);
    276                         annotations.add(annot);
    277                     } else {
    278                         logger.error("ANNOTATES relation does not start with ANNOTATION: " + ann);
    279                     }
    280                 }
    281             }
    282         }
    283         if (userUri != null) {
    284             // there should be only one
    285             Node person = getNodeIndex(NodeTypes.PERSON).get("uri", userUri).getSingle();
    286             if (person != null) {
    287                 Iterable<Relationship> relations = person.getRelationships(RelationTypes.CREATED);
    288                 for (Relationship relation : relations) {
    289                     Node ann = relation.getEndNode();
    290                     if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
    291                         Annotation annot = createAnnotationFromNode(ann);
    292                         annotations.add(annot);
    293                     } else {
    294                         logger.error("CREATED relation does not end with ANNOTATION: " + ann);
    295                     }
    296                 }
    297             }
    298         }
    299         return annotations;
    300     }
    301 
    302     protected Relationship getOrCreateRelation(Node start, RelationshipType type, Node end) {
    303         if (start.hasRelationship()) {
    304             // there are relations
    305             Iterable<Relationship> rels = start.getRelationships(type, Direction.OUTGOING);
    306             for (Relationship rel : rels) {
    307                 if (rel.getEndNode().equals(end)) {
    308                     // relation exists
    309                     return rel;
    310                 }
    311             }
    312         }
    313         // create new one
    314         Relationship rel;
    315         Transaction tx = graphDb.beginTx();
    316         try {
    317             rel = start.createRelationshipTo(end, type);
    318             tx.success();
    319         } finally {
    320             tx.finish();
    321         }
    322         return rel;
    323     }
    324 
    325     protected Node getOrCreateAnnotationNode(String id) {
    326         Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION);
    327         IndexHits<Node> annotations = idx.get("id", id);
    328         Node annotation = annotations.getSingle();
    329         if (annotation == null) {
    330             // does not exist yet
    331             Transaction tx = graphDb.beginTx();
    332             try {
    333                 annotation = graphDb.createNode();
    334                 annotation.setProperty("TYPE", NodeTypes.ANNOTATION.name());
    335                 annotation.setProperty("id", id);
    336                 idx.add(annotation, "id", id);
    337                 tx.success();
    338             } finally {
    339                 tx.finish();
    340             }
    341         }
    342         return annotation;
    343     }
    344 
    345     protected Node getOrCreateTargetNode(String uri) {
    346         Index<Node> idx = getNodeIndex(NodeTypes.TARGET);
    347         IndexHits<Node> targets = idx.get("uri", uri);
    348         Node target = targets.getSingle();
    349         if (target == null) {
    350             // does not exist yet
    351             Transaction tx = graphDb.beginTx();
    352             try {
    353                 target = graphDb.createNode();
    354                 target.setProperty("TYPE", NodeTypes.TARGET.name());
    355                 target.setProperty("uri", uri);
    356                 idx.add(target, "uri", uri);
    357                 tx.success();
    358             } finally {
    359                 tx.finish();
    360             }
    361         }
    362         return target;
    363     }
    364 
    365     protected Node getOrCreatePersonNode(Actor actor) {
    366         /*
    367          * // Person is identified by URI Index<Node> idx =
    368          * getNodeIndex(NodeTypes.PERSON); IndexHits<Node> persons =
    369          * idx.get("uri", uri); Node person = persons.getSingle(); if (person ==
    370          * null) { // does not exist yet Transaction tx = graphDb.beginTx(); try
    371          * { person = graphDb.createNode(); person.setProperty("TYPE",
    372          * NodeTypes.PERSON.name()); person.setProperty("uri", uri);
    373          * idx.add(person, "uri", uri); if (name != null) {
    374          * person.setProperty("name", name); } tx.success(); } finally {
    375          * tx.finish(); } } return person;
    376          */
    377         return null;
    378     }
    379 
    380     /**
    381      * Create or update permissions relations for an annotation.
    382      *
    383      * @param annotNode
    384      * @param type
    385      * @param annot
    386      */
    387     protected void setPermissionRelation(Node annotNode, RelationTypes type, Actor actor) {
    388         Node newActorNode = null;
    389         if (actor != null) {
    390             newActorNode = getOrCreatePersonNode(actor);
    391         }
    392         Relationship rel = getRelation(annotNode, type, null);
    393         if (rel != null) {
    394             // relation exists
    395             Node oldActorNode = rel.getEndNode();
    396             if (!oldActorNode.equals(newActorNode)) {
    397                 // new admin is different
    398                 rel.delete();
    399                 if (newActorNode != null) {
    400                     rel = getOrCreateRelation(annotNode, type, newActorNode);
    401                 }
    402             }
    403         } else {
    404             // no relation yet
    405             if (newActorNode != null) {
    406                 rel = getOrCreateRelation(annotNode, type, newActorNode);
    407             }
    408         }
    409     }
    410 
    411     /**
    412      * Unindexes and deletes given Node if it has no relations.
    413      *
    414      * @param node
    415      */
    416     protected void deleteNode(Node node) {
    417         Transaction tx = graphDb.beginTx();
    418         try {
    419             if (node.hasRelationship()) {
    420                 logger.error("deleteNode: unable to delete: Node still has relations.");
    421             } else {
    422                 String ts = (String) node.getProperty("TYPE", null);
    423                 try {
    424                     NodeTypes type = NodeTypes.valueOf(ts);
    425                     getNodeIndex(type).remove(node);
    426                 } catch (Exception e) {
    427                     logger.error("deleteNode: unable to get TYPE of node: " + node);
    428                 }
    429                 node.delete();
    430             }
    431             tx.success();
    432         } finally {
    433             tx.finish();
    434         }
    435     }
    436 
    437     protected Relationship getRelation(Node start, RelationTypes type, Direction direction) {
    438         Iterable<Relationship> rels;
    439         if (direction == null) {
    440             // ignore direction
    441             rels = start.getRelationships(type);
    442         } else {
    443             rels = start.getRelationships(type, direction);
    444         }
    445         for (Relationship rel : rels) {
    446             return rel;
    447         }
    448         return null;
    449     }
    450 
    451     /**
    452      * Erzeuge eine urn aus der aktuellen Zeit in millis
    453      *
    454      * @return
    455      */
    456     private String createRessourceURI(String prefix) {
    457 
    458         Calendar cal = Calendar.getInstance();
    459 
    460         long time = cal.getTimeInMillis();
    461 
    462         return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time);
    463 
    464     }
     32        protected static Logger logger = Logger.getLogger(AnnotationStore.class);
     33
     34        protected GraphDatabaseService graphDb;
     35
     36        public static enum NodeTypes {
     37                ANNOTATION, PERSON, TARGET
     38        }
     39
     40        protected List<Index<Node>> nodeIndexes;
     41
     42        public static enum RelationTypes implements RelationshipType {
     43                ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ
     44        }
     45
     46        public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/";
     47
     48        public AnnotationStore(GraphDatabaseService graphDb) {
     49                super();
     50                this.graphDb = graphDb;
     51                nodeIndexes = new ArrayList<Index<Node>>(3);
     52                // List.set(enum.ordinal(), val) seems not to work.
     53                nodeIndexes.add(NodeTypes.ANNOTATION.ordinal(), graphDb.index()
     54                                .forNodes("annotations"));
     55                nodeIndexes.add(NodeTypes.PERSON.ordinal(),
     56                                graphDb.index().forNodes("persons"));
     57                nodeIndexes.add(NodeTypes.TARGET.ordinal(),
     58                                graphDb.index().forNodes("targets"));
     59        }
     60
     61        protected Index<Node> getNodeIndex(NodeTypes type) {
     62                return nodeIndexes.get(type.ordinal());
     63        }
     64
     65        /**
     66         * Returns the Annotation with the given id.
     67         *
     68         * @param id
     69         * @return
     70         */
     71        public Annotation getAnnotationById(String id) {
     72                Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id)
     73                                .getSingle();
     74                Annotation annot = createAnnotationFromNode(annotNode);
     75                return annot;
     76        }
     77
     78        /**
     79         * Returns an Annotation object from an annotation-Node.
     80         *
     81         * @param annotNode
     82         * @return
     83         */
     84        public Annotation createAnnotationFromNode(Node annotNode) {
     85                Annotation annot = new Annotation();
     86                annot.setUri((String) annotNode.getProperty("id", null));
     87                annot.setBodyText((String) annotNode.getProperty("bodyText", null));
     88                annot.setBodyUri((String) annotNode.getProperty("bodyUri", null));
     89                // get annotation target from relation
     90                Relationship targetRel = getRelation(annotNode,
     91                                RelationTypes.ANNOTATES, null);
     92                if (targetRel != null) {
     93                        Node target = targetRel.getEndNode();
     94                        annot.setTargetBaseUri((String) target.getProperty("uri", null));
     95                } else {
     96                        logger.error("annotation " + annotNode + " has no target node!");
     97                }
     98                annot.setTargetFragment((String) annotNode.getProperty(
     99                                "targetFragment", null));
     100                String ft = (String) annotNode.getProperty("fragmentType", null);
     101                if (ft != null) {
     102                        annot.setFragmentType(FragmentTypes.valueOf(ft));
     103                }
     104                // get creator from relation
     105                Relationship creatorRel = getRelation(annotNode, RelationTypes.CREATED,
     106                                null);
     107                if (creatorRel != null) {
     108                        Node creatorNode = creatorRel.getStartNode();
     109                        Actor creator = createActorFromNode(creatorNode);
     110                        annot.setCreator(creator);
     111                } else {
     112                        logger.error("annotation " + annotNode + " has no creator node!");
     113                }
     114                // get creation date
     115                annot.setCreated((String) annotNode.getProperty("created", null));
     116                // get permissions
     117                Relationship adminRel = getRelation(annotNode,
     118                                RelationTypes.PERMITS_ADMIN, null);
     119                if (adminRel != null) {
     120                        Node adminNode = adminRel.getEndNode();
     121                        Actor admin = createActorFromNode(adminNode);
     122                        annot.setAdminPermission(admin);
     123                }
     124                Relationship deleteRel = getRelation(annotNode,
     125                                RelationTypes.PERMITS_DELETE, null);
     126                if (deleteRel != null) {
     127                        Node deleteNode = deleteRel.getEndNode();
     128                        Actor delete = createActorFromNode(deleteNode);
     129                        annot.setDeletePermission(delete);
     130                }
     131                Relationship updateRel = getRelation(annotNode,
     132                                RelationTypes.PERMITS_UPDATE, null);
     133                if (updateRel != null) {
     134                        Node updateNode = updateRel.getEndNode();
     135                        Actor update = createActorFromNode(updateNode);
     136                        annot.setUpdatePermission(update);
     137                }
     138                Relationship readRel = getRelation(annotNode,
     139                                RelationTypes.PERMITS_READ, null);
     140                if (readRel != null) {
     141                        Node readNode = readRel.getEndNode();
     142                        Actor read = createActorFromNode(readNode);
     143                        annot.setReadPermission(read);
     144                }
     145
     146                return annot;
     147        }
     148
     149        /**
     150         * Returns an Actor object from a node.
     151         *
     152         * @param actorNode
     153         * @return
     154         */
     155        protected Actor createActorFromNode(Node actorNode) {
     156                String uri = (String) actorNode.getProperty("uri", null);
     157                String name = (String) actorNode.getProperty("name", null);
     158                String type = (String) actorNode.getProperty("TYPE", null);
     159                if (type != null && type.equals("PERSON")) {
     160                        return new Person(uri, name);
     161                } else if (type != null && type.equals("GROUP")) {
     162                        return new Group(uri, name);
     163                }
     164                return null;
     165        }
     166
     167        /**
     168         * Store a new annotation in the store or update an existing one. Returns
     169         * the stored annotation.
     170         *
     171         * @param annot
     172         * @return
     173         */
     174        public Annotation storeAnnotation(Annotation annot) {
     175                Node annotNode = null;
     176                Transaction tx = graphDb.beginTx();
     177                try {
     178                        /*
     179                         * create or get the annotation
     180                         */
     181                        String id = annot.getUri();
     182                        if (id == null) {
     183                                id = createRessourceURI("annot:");
     184                        }
     185                        annotNode = getOrCreateAnnotationNode(id);
     186
     187                        /*
     188                         * the annotation body
     189                         */
     190                        String bodyText = annot.getBodyText();
     191                        if (bodyText != null) {
     192                                annotNode.setProperty("bodyText", bodyText);
     193                        }
     194                        String bodyUri = annot.getBodyUri();
     195                        if (bodyUri != null) {
     196                                annotNode.setProperty("bodyUri", bodyUri);
     197                        }
     198
     199                        /*
     200                         * the annotation target
     201                         */
     202                        String targetBaseUri = annot.getTargetBaseUri();
     203                        if (targetBaseUri != null) {
     204                                Node target = getOrCreateTargetNode(targetBaseUri);
     205                                getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target);
     206                        }
     207
     208                        /*
     209                         * The fragment part of the annotation target.
     210                         */
     211                        String targetFragment = annot.getTargetFragment();
     212                        FragmentTypes fragmentType = annot.getFragmentType();
     213                        if (targetFragment != null) {
     214                                annotNode.setProperty("targetFragment", targetFragment);
     215                                annotNode.setProperty("fragmentType", fragmentType.name());
     216                        }
     217
     218                        /*
     219                         * The creator of this annotation.
     220                         */
     221                        Actor creator = annot.getCreator();
     222                        if (creator != null) {
     223                                Node creatorNode = getOrCreatePersonNode(creator);
     224                                getOrCreateRelation(creatorNode, RelationTypes.CREATED,
     225                                                annotNode);
     226                        }
     227
     228                        /*
     229                         * The creation date of this annotation.
     230                         */
     231                        String created = annot.getCreated();
     232                        if (created != null) {
     233                                annotNode.setProperty("created", created);
     234                        }
     235
     236                        /*
     237                         * Permissions for this annotation.
     238                         */
     239                        setPermissionRelation(annotNode, RelationTypes.PERMITS_ADMIN,
     240                                        annot.getAdminPermission());
     241                        setPermissionRelation(annotNode, RelationTypes.PERMITS_DELETE,
     242                                        annot.getDeletePermission());
     243                        setPermissionRelation(annotNode, RelationTypes.PERMITS_UPDATE,
     244                                        annot.getUpdatePermission());
     245                        setPermissionRelation(annotNode, RelationTypes.PERMITS_READ,
     246                                        annot.getReadPermission());
     247
     248                        tx.success();
     249                } finally {
     250                        tx.finish();
     251                }
     252
     253                // re-read and return annotation
     254                Annotation storedAnnot = createAnnotationFromNode(annotNode);
     255                return storedAnnot;
     256        }
     257
     258        /**
     259         * Deletes the annotation with the given id.
     260         *
     261         * @param id
     262         */
     263        public void deleteById(String id) {
     264                Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id)
     265                                .getSingle();
     266                if (annotNode != null) {
     267                        // delete related objects
     268                        Transaction tx = graphDb.beginTx();
     269                        try {
     270                                for (Relationship rel : annotNode.getRelationships()) {
     271                                        // delete relation and the related node if it has no other
     272                                        // relations
     273                                        Node other = rel.getOtherNode(annotNode);
     274                                        rel.delete();
     275                                        if (!other.hasRelationship()) {
     276                                                deleteNode(other);
     277                                        }
     278                                }
     279                                if (!annotNode.hasRelationship()) {
     280                                        deleteNode(annotNode);
     281                                } else {
     282                                        logger.error("deleteById: unable to delete: Node still has relations.");
     283                                }
     284                                tx.success();
     285                        } finally {
     286                                tx.finish();
     287                        }
     288                }
     289        }
     290
     291        /**
     292         * Returns all annotations with the given uri and/or user.
     293         *
     294         * @param uri
     295         * @param userUri
     296         * @param limit
     297         * @param offset
     298         * @return
     299         */
     300        public List<Annotation> searchByUriUser(String targetUri, String userUri,
     301                        String limit, String offset) {
     302                List<Annotation> annotations = new ArrayList<Annotation>();
     303                if (targetUri != null) {
     304                        // there should be only one
     305                        Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri)
     306                                        .getSingle();
     307                        if (target != null) {
     308                                Iterable<Relationship> relations = target
     309                                                .getRelationships(RelationTypes.ANNOTATES);
     310                                for (Relationship relation : relations) {
     311                                        Node ann = relation.getStartNode();
     312                                        if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
     313                                                Annotation annot = createAnnotationFromNode(ann);
     314                                                annotations.add(annot);
     315                                        } else {
     316                                                logger.error("ANNOTATES relation does not start with ANNOTATION: "
     317                                                                + ann);
     318                                        }
     319                                }
     320                        }
     321                }
     322                if (userUri != null) {
     323                        // there should be only one
     324                        Node person = getNodeIndex(NodeTypes.PERSON).get("uri", userUri)
     325                                        .getSingle();
     326                        if (person != null) {
     327                                Iterable<Relationship> relations = person
     328                                                .getRelationships(RelationTypes.CREATED);
     329                                for (Relationship relation : relations) {
     330                                        Node ann = relation.getEndNode();
     331                                        if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
     332                                                Annotation annot = createAnnotationFromNode(ann);
     333                                                annotations.add(annot);
     334                                        } else {
     335                                                logger.error("CREATED relation does not end with ANNOTATION: "
     336                                                                + ann);
     337                                        }
     338                                }
     339                        }
     340                }
     341                return annotations;
     342        }
     343
     344        protected Relationship getOrCreateRelation(Node start,
     345                        RelationshipType type, Node end) {
     346                if (start.hasRelationship()) {
     347                        // there are relations
     348                        Iterable<Relationship> rels = start.getRelationships(type,
     349                                        Direction.OUTGOING);
     350                        for (Relationship rel : rels) {
     351                                if (rel.getEndNode().equals(end)) {
     352                                        // relation exists
     353                                        return rel;
     354                                }
     355                        }
     356                }
     357                // create new one
     358                Relationship rel;
     359                Transaction tx = graphDb.beginTx();
     360                try {
     361                        rel = start.createRelationshipTo(end, type);
     362                        tx.success();
     363                } finally {
     364                        tx.finish();
     365                }
     366                return rel;
     367        }
     368
     369        protected Node getOrCreateAnnotationNode(String id) {
     370                Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION);
     371                IndexHits<Node> annotations = idx.get("id", id);
     372                Node annotation = annotations.getSingle();
     373                if (annotation == null) {
     374                        // does not exist yet
     375                        Transaction tx = graphDb.beginTx();
     376                        try {
     377                                annotation = graphDb.createNode();
     378                                annotation.setProperty("TYPE", NodeTypes.ANNOTATION.name());
     379                                annotation.setProperty("id", id);
     380                                idx.add(annotation, "id", id);
     381                                tx.success();
     382                        } finally {
     383                                tx.finish();
     384                        }
     385                }
     386                return annotation;
     387        }
     388
     389        protected Node getOrCreateTargetNode(String uri) {
     390                Index<Node> idx = getNodeIndex(NodeTypes.TARGET);
     391                IndexHits<Node> targets = idx.get("uri", uri);
     392                Node target = targets.getSingle();
     393                if (target == null) {
     394                        // does not exist yet
     395                        Transaction tx = graphDb.beginTx();
     396                        try {
     397                                target = graphDb.createNode();
     398                                target.setProperty("TYPE", NodeTypes.TARGET.name());
     399                                target.setProperty("uri", uri);
     400                                idx.add(target, "uri", uri);
     401                                tx.success();
     402                        } finally {
     403                                tx.finish();
     404                        }
     405                }
     406                return target;
     407        }
     408
     409        protected Node getOrCreatePersonNode(Actor actor) {
     410                // Person is identified by URI
     411                String uri = actor.getUriString();
     412                String name = actor.getName();
     413                Index<Node> idx = getNodeIndex(NodeTypes.PERSON);
     414                IndexHits<Node> persons = idx.get("uri", uri);
     415                Node person = persons.getSingle();
     416                if (person == null) {
     417                        // does not exist yet
     418                        Transaction tx = graphDb.beginTx();
     419                        try {
     420                                person = graphDb.createNode();
     421                                person.setProperty("TYPE", NodeTypes.PERSON.name());
     422                                person.setProperty("uri", uri);
     423                                idx.add(person, "uri", uri);
     424                                if (name != null) {
     425                                        person.setProperty("name", name);
     426                                }
     427                                tx.success();
     428                        } finally {
     429                                tx.finish();
     430                        }
     431                }
     432                return person;
     433        }
     434
     435        /**
     436         * Create or update permissions relations for an annotation.
     437         *
     438         * @param annotNode
     439         * @param type
     440         * @param annot
     441         */
     442        protected void setPermissionRelation(Node annotNode, RelationTypes type,
     443                        Actor actor) {
     444                Node newActorNode = null;
     445                if (actor != null) {
     446                        newActorNode = getOrCreatePersonNode(actor);
     447                }
     448                Relationship rel = getRelation(annotNode, type, null);
     449                if (rel != null) {
     450                        // relation exists
     451                        Node oldActorNode = rel.getEndNode();
     452                        if (!oldActorNode.equals(newActorNode)) {
     453                                // new admin is different
     454                                rel.delete();
     455                                if (newActorNode != null) {
     456                                        rel = getOrCreateRelation(annotNode, type, newActorNode);
     457                                }
     458                        }
     459                } else {
     460                        // no relation yet
     461                        if (newActorNode != null) {
     462                                rel = getOrCreateRelation(annotNode, type, newActorNode);
     463                        }
     464                }
     465        }
     466
     467        /**
     468         * Unindexes and deletes given Node if it has no relations.
     469         *
     470         * @param node
     471         */
     472        protected void deleteNode(Node node) {
     473                Transaction tx = graphDb.beginTx();
     474                try {
     475                        if (node.hasRelationship()) {
     476                                logger.error("deleteNode: unable to delete: Node still has relations.");
     477                        } else {
     478                                String ts = (String) node.getProperty("TYPE", null);
     479                                try {
     480                                        NodeTypes type = NodeTypes.valueOf(ts);
     481                                        getNodeIndex(type).remove(node);
     482                                } catch (Exception e) {
     483                                        logger.error("deleteNode: unable to get TYPE of node: "
     484                                                        + node);
     485                                }
     486                                node.delete();
     487                        }
     488                        tx.success();
     489                } finally {
     490                        tx.finish();
     491                }
     492        }
     493
     494        protected Relationship getRelation(Node start, RelationTypes type,
     495                        Direction direction) {
     496                Iterable<Relationship> rels;
     497                if (direction == null) {
     498                        // ignore direction
     499                        rels = start.getRelationships(type);
     500                } else {
     501                        rels = start.getRelationships(type, direction);
     502                }
     503                for (Relationship rel : rels) {
     504                        return rel;
     505                }
     506                return null;
     507        }
     508
     509        /**
     510         * Erzeuge eine urn aus der aktuellen Zeit in millis
     511         *
     512         * @return
     513         */
     514        private String createRessourceURI(String prefix) {
     515
     516                Calendar cal = Calendar.getInstance();
     517
     518                long time = cal.getTimeInMillis();
     519
     520                return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time);
     521
     522        }
    465523
    466524}
Note: See TracChangeset for help on using the changeset viewer.