Ignore:
Timestamp:
Sep 4, 2012, 6:02:59 PM (12 years ago)
Author:
casties
Branch:
default
Message:

CLOSED - # 252: Tags for Annotations
https://it-dev.mpiwg-berlin.mpg.de/tracs/mpdl-project-software/ticket/252

File:
1 edited

Legend:

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

    r15 r16  
    66import java.util.ArrayList;
    77import java.util.Calendar;
     8import java.util.HashSet;
    89import java.util.List;
     10import java.util.Set;
    911
    1012import org.apache.log4j.Logger;
     
    3537
    3638    public static enum NodeTypes {
    37         ANNOTATION, PERSON, TARGET, GROUP 
     39        ANNOTATION, PERSON, TARGET, GROUP, TAG
    3840    }
    3941
     
    4143
    4244    public static enum RelationTypes implements RelationshipType {
    43         ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ, MEMBER_OF
     45        ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ, MEMBER_OF, HAS_TAG
    4446    }
    4547
     
    4951        super();
    5052        this.graphDb = graphDb;
    51         nodeIndexes = new ArrayList<Index<Node>>(3);
     53        nodeIndexes = new ArrayList<Index<Node>>(5);
    5254        // List.set(enum.ordinal(), val) seems not to work.
    5355        nodeIndexes.add(NodeTypes.ANNOTATION.ordinal(), graphDb.index().forNodes("annotations"));
     
    5557        nodeIndexes.add(NodeTypes.TARGET.ordinal(), graphDb.index().forNodes("targets"));
    5658        nodeIndexes.add(NodeTypes.GROUP.ordinal(), graphDb.index().forNodes("groups"));
     59        nodeIndexes.add(NodeTypes.TAG.ordinal(), graphDb.index().forNodes("tags"));
    5760    }
    5861
     
    7174    }
    7275
    73    
    7476    /**
    7577     * Returns List of Groups the person is member of.
     
    8688            // make sure we're getting a group
    8789            if (!(group instanceof Group)) {
    88                 logger.error("target of MEMBER_OF is not GROUP! rel="+rel);
     90                logger.error("target of MEMBER_OF is not GROUP! rel=" + rel);
    8991                continue;
    9092            }
     
    9395        return groups;
    9496    }
    95    
     97
    9698    /**
    9799     * Returns if person with uri is in Group group.
     
    104106        Node pn = getPersonNodeByUri(person.getUriString());
    105107        if (pn == null) return false;
    106         // optimised version of getGroupsForPersonNode
     108        // optimized version of getGroupsForPersonNode
    107109        Iterable<Relationship> rels = pn.getRelationships(RelationTypes.MEMBER_OF);
    108110        for (Relationship rel : rels) {
     
    114116        return false;
    115117    }
    116    
     118
    117119    /**
    118120     * Returns the Annotation with the given id.
     
    138140        annot.setBodyText((String) annotNode.getProperty("bodyText", null));
    139141        annot.setBodyUri((String) annotNode.getProperty("bodyUri", null));
    140         // get annotation target from relation
     142        /*
     143         * get annotation target from relation
     144         */
    141145        Relationship targetRel = getRelation(annotNode, RelationTypes.ANNOTATES, null);
    142146        if (targetRel != null) {
     
    151155            annot.setFragmentType(FragmentTypes.valueOf(ft));
    152156        }
    153         // get creator from relation
     157        /*
     158         * get creator from relation
     159         */
    154160        Relationship creatorRel = getRelation(annotNode, RelationTypes.CREATED, null);
    155161        if (creatorRel != null) {
     
    160166            logger.error("annotation " + annotNode + " has no creator node!");
    161167        }
    162         // get creation date
     168        /*
     169         * get creation date
     170         */
    163171        annot.setCreated((String) annotNode.getProperty("created", null));
    164         // get permissions
     172        /*
     173         * get permissions
     174         */
    165175        Relationship adminRel = getRelation(annotNode, RelationTypes.PERMITS_ADMIN, null);
    166176        if (adminRel != null) {
     
    187197            annot.setReadPermission(read);
    188198        }
     199        /*
     200         * get tags
     201         */
     202        Set<String> tags = new HashSet<String>();
     203        for (Relationship rel : annotNode.getRelationships(RelationTypes.HAS_TAG)) {
     204            String tag = (String) rel.getEndNode().getProperty("name", null);
     205            if (tag != null) {
     206                tags.add(tag);
     207            }
     208        }
     209        annot.setTags(tags);
    189210
    190211        return annot;
     
    286307            setPermissionRelation(annotNode, RelationTypes.PERMITS_READ, annot.getReadPermission());
    287308
     309            /*
     310             * Tags on this annotation.
     311             */
     312            Set<String> newTags = annot.getTags();
     313            // we ignore existing tags if tags == null
     314            if (newTags != null) {
     315                List<Relationship> oldHasTags = new ArrayList<Relationship>();
     316                for (Relationship rel : annotNode.getRelationships(RelationTypes.HAS_TAG)) {
     317                    oldHasTags.add(rel);
     318                }
     319                // adjust to new tags
     320                if (newTags.isEmpty()) {
     321                    // remove old tags
     322                    if (!oldHasTags.isEmpty()) {
     323                        for (Relationship rel : oldHasTags) {
     324                            rel.delete();
     325                            // TODO: should we delete orphan nodes too?
     326                        }
     327                    }
     328                } else {
     329                    if (!oldHasTags.isEmpty()) {
     330                        // adjust old tags
     331                        for (Relationship rel : oldHasTags) {
     332                            String oldTag = (String) rel.getEndNode().getProperty("name", null);
     333                            if (newTags.contains(oldTag)) {
     334                                // tag exists
     335                                newTags.remove(oldTag);
     336                            } else {
     337                                // tag exists no longer
     338                                rel.delete();
     339                                // TODO: should we delete orphan nodes too?
     340                            }
     341                        }
     342                    }
     343                    if (!newTags.isEmpty()) {
     344                        // still tags to add
     345                        for (String tag : newTags) {
     346                            // create new tag
     347                            Node tagNode = getOrCreateTagNode(tag);
     348                            getOrCreateRelation(annotNode, RelationTypes.HAS_TAG, tagNode);
     349                        }
     350                    }
     351
     352                }
     353            }
    288354            tx.success();
    289355        } finally {
     
    371437            }
    372438        }
     439        // TODO: if both uri and user are given we should intersect
    373440        return annotations;
    374441    }
    375442
     443    /**
     444     * Returns Relationship of type from Node start to Node end. Creates one if
     445     * it doesn't exist.
     446     *
     447     * @param start
     448     * @param type
     449     * @param end
     450     * @return
     451     */
    376452    protected Relationship getOrCreateRelation(Node start, RelationshipType type, Node end) {
    377453        if (start.hasRelationship()) {
     
    458534                    person.setProperty("TYPE", NodeTypes.GROUP.name());
    459535                } else {
    460                     person.setProperty("TYPE", NodeTypes.PERSON.name());                   
     536                    person.setProperty("TYPE", NodeTypes.PERSON.name());
    461537                }
    462538                person.setProperty("uri", uri);
     
    474550        }
    475551        return person;
     552    }
     553
     554    protected Node getOrCreateTagNode(String tagname) {
     555        Index<Node> idx = getNodeIndex(NodeTypes.TAG);
     556        IndexHits<Node> tags = idx.get("name", tagname);
     557        Node tag = tags.getSingle();
     558        if (tag == null) {
     559            // does not exist yet
     560            Transaction tx = graphDb.beginTx();
     561            try {
     562                tag = graphDb.createNode();
     563                tag.setProperty("TYPE", NodeTypes.TAG.name());
     564                tag.setProperty("name", tagname);
     565                idx.add(tag, "name", tagname);
     566                tx.success();
     567            } finally {
     568                tx.finish();
     569            }
     570        }
     571        return tag;
    476572    }
    477573
     
    533629    }
    534630
    535     /** returns the (first) Relationship of RelationTypes type from Node start.
    536      * 
     631    /**
     632     * returns the (first) Relationship of RelationTypes type from Node start.
     633     *
    537634     * @param start
    538635     * @param type
     
    549646        }
    550647        for (Relationship rel : rels) {
     648            // just the first one
    551649            return rel;
    552650        }
Note: See TracChangeset for help on using the changeset viewer.