/* * CATMA Computer Aided Text Markup and Analysis * * Copyright (C) 2009-2013 University Of Hamburg * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.catma.document.standoffmarkup.usermarkup; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import de.catma.document.AccessMode; import de.catma.document.source.ContentInfoSet; import de.catma.tag.Property; import de.catma.tag.PropertyValueList; import de.catma.tag.TagDefinition; import de.catma.tag.TagInstance; import de.catma.tag.TagLibrary; import de.catma.tag.TagsetDefinition; import de.catma.util.IDGenerator; import de.catma.util.Pair; /** * A collection of user generated markup in the form of {@link TagReference}s. * * @author marco.petris@web.de * */ public class UserMarkupCollection { private String id; private ContentInfoSet contentInfoSet; private TagLibrary tagLibrary; private List<TagReference> tagReferences; private AccessMode accessMode; /** * @param id the identifier of the collections (depends on the repository) * @param contentInfoSet the bibliographical metadata of this collection * @param tagLibrary the internal library with all relevant {@link TagsetDefinition}s. */ public UserMarkupCollection( String id, ContentInfoSet contentInfoSet, TagLibrary tagLibrary) { this(id, contentInfoSet, tagLibrary, new ArrayList<TagReference>(), AccessMode.WRITE); } /** * @param id the identifier of the collections (depends on the repository) * @param contentInfoSet the bibliographical metadata of this collection * @param tagLibrary the internal library with all relevant {@link TagsetDefinition}s. * @param tagReferences referenced text ranges and referencing {@link TagInstance}s. */ public UserMarkupCollection( String id, ContentInfoSet contentInfoSet, TagLibrary tagLibrary, List<TagReference> tagReferences, AccessMode accessMode) { this.id = id; this.contentInfoSet = contentInfoSet; this.tagLibrary = tagLibrary; this.tagReferences = tagReferences; this.accessMode = accessMode; } public UserMarkupCollection(UserMarkupCollection userMarkupCollection) throws URISyntaxException { this( null, new ContentInfoSet(userMarkupCollection.getContentInfoSet()), new TagLibrary(userMarkupCollection.getTagLibrary())); IDGenerator idGenerator = new IDGenerator(); Map<String,TagInstance> copiedTagInstances = new HashMap<String,TagInstance>(); for (TagReference tr : userMarkupCollection.getTagReferences()) { TagInstance tagInstance = tr.getTagInstance(); TagInstance copiedInstance = copiedTagInstances.get(tagInstance.getUuid()); if (copiedInstance == null) { TagDefinition tagDefinition = getTagLibrary().getTagDefinition(tagInstance.getTagDefinition().getUuid()); copiedInstance = new TagInstance(idGenerator.generate(), tagDefinition); for (Property property : tagInstance.getSystemProperties()) { copiedInstance.addSystemProperty( new Property( tagDefinition.getPropertyDefinition( property.getPropertyDefinition().getUuid()), new PropertyValueList(property.getPropertyValueList()))); } for (Property property : tagInstance.getUserDefinedProperties()) { copiedInstance.addSystemProperty( new Property( tagDefinition.getPropertyDefinition( property.getPropertyDefinition().getUuid()), new PropertyValueList(property.getPropertyValueList()))); } copiedTagInstances.put(tagInstance.getUuid(), copiedInstance); } addTagReference( new TagReference(copiedInstance, tr.getTarget().toString(), tr.getRange())); } } /** * @return the internal library with all relevant {@link TagsetDefinition}s. */ public TagLibrary getTagLibrary() { return tagLibrary; } /** * @return unmodifiable version of referenced text ranges and referencing {@link TagInstance}s. */ public List<TagReference> getTagReferences() { return Collections.unmodifiableList(tagReferences); } /** * @param tagDefinition return all references with this tagdefinition (<b>excluding</b> * all references that have a tag definition that is a child of the given definition, i. e. * this is not a deep list of references) * * @return the matching references */ public List<TagReference> getTagReferences(TagDefinition tagDefinition) { return getTagReferences(tagDefinition, false); } /** * @param tagDefinition return all references with this tagdefinition * @param withChildReferences <code>true</code> include child tag definitions as well (deep list) or <code>false</code> exclude * child tag definitions (shallow list) * @return a list of tag references */ public List<TagReference> getTagReferences( TagDefinition tagDefinition, boolean withChildReferences) { List<TagReference> result = new ArrayList<TagReference>(); Set<String> tagDefinitionIDs = new HashSet<String>(); tagDefinitionIDs.add(tagDefinition.getUuid()); if (withChildReferences) { tagDefinitionIDs.addAll(getChildIDs(tagDefinition)); } for (TagReference tr : tagReferences) { if (tagDefinitionIDs.contains(tr.getTagDefinition().getUuid())) { result.add(tr); } } return result; } /** * @param tagDefinition * @return a set of {@link TagDefinition#getId() IDs} of tag definitions that * are children of the given definition (deep list) */ public Set<String> getChildIDs(TagDefinition tagDefinition) { return tagLibrary.getChildIDs(tagDefinition); } /** * @param tagDefinition * @return a set of tag definitions that are children of the given * definition (deep list) */ public List<TagDefinition> getChildren(TagDefinition tagDefinition) { return tagLibrary.getChildren(tagDefinition); } @Override public String toString() { return contentInfoSet.getTitle(); } public void addTagReferences(List<TagReference> tagReferences) { this.tagReferences.addAll(tagReferences); } public void addTagReference(TagReference tagReference) { this.tagReferences.add(tagReference); } /** * @return the identifier of this collection (depends on the repository) */ public String getId() { return id; } /** * @return name of this collection */ public String getName() { return contentInfoSet.getTitle(); } /** * @return metadata for this collection */ public ContentInfoSet getContentInfoSet() { return contentInfoSet; } /** * @return <code>true</code> if there are no tag references in this collection */ public boolean isEmpty() { return tagReferences.isEmpty(); } /** * @param tagLibrary the internal library with all relevant {@link TagsetDefinition}s * must correspond to the tag definitions of the tag intances of the tag references * of this collection */ public void setTagLibrary(TagLibrary tagLibrary) { this.tagLibrary = tagLibrary; } public void setId(String id) { this.id = id; } /** * {@link TagInstance#synchronizeProperties() Synchronizes} all the Tag Instances. */ public void synchronizeTagInstances() { HashSet<TagInstance> tagInstances = new HashSet<TagInstance>(); for (TagReference tr : tagReferences) { tagInstances.add(tr.getTagInstance()); } for (TagInstance ti : tagInstances) { if (getTagLibrary().getTagsetDefinition(ti.getTagDefinition()) != null) { //TODO: handle move between TagsetDefinitions ti.synchronizeProperties(); } else { tagReferences.removeAll(getTagReferences(ti.getUuid())); } } } /** * @param tagInstanceID * @return all references which belong to the {@link TagInstance} with the given ID */ public List<TagReference> getTagReferences(String tagInstanceID) { List<TagReference> result = new ArrayList<TagReference>(); for (TagReference tr : getTagReferences()) { if (tr.getTagInstanceID().equals(tagInstanceID)) { result.add(tr); } } return result; } /** * @param ti * @return all references which belong to the given TagInstance */ public List<TagReference> getTagReferences(TagInstance ti) { return getTagReferences(ti.getUuid()); } /** * @param instanceID * @return <code>true</code> if there is a TagReference with the given TagInstance's ID */ public boolean hasTagInstance(String instanceID) { for (TagReference tr : getTagReferences()) { if (tr.getTagInstanceID().equals(instanceID)) { return true; } } return false; } /** * @param tagReferences references to be removed */ public void removeTagReferences(List<TagReference> tagReferences) { this.tagReferences.removeAll(tagReferences); } /** * @param tagsetDefinition * @return all references that have TagInstances with the given tag def */ public List<TagReference> getTagReferences(TagsetDefinition tagsetDefinition) { ArrayList<TagReference> result = new ArrayList<TagReference>(); if (getTagLibrary().contains(tagsetDefinition)) { for (TagDefinition td : getTagLibrary().getTagsetDefinition( tagsetDefinition.getUuid())) { result.addAll(getTagReferences(td)); } } return result; } /** * @param contentInfoSet Metadata for this collection */ void setContentInfoSet(ContentInfoSet contentInfoSet) { this.contentInfoSet = contentInfoSet; } /** * @param instanceID the {@link TagInstance#getUuid() uuid} of the TagInstance * @return a {@link Pair} with the {@link TagLibrary#getTagPath(TagDefinition) Tag path} * and the corresponding {@link TagInstance}. */ public Pair<String,TagInstance> getInstance(String instanceID) { for (TagReference tr : tagReferences) { if (tr.getTagInstanceID().equals(instanceID)) { return new Pair<String,TagInstance>( this.tagLibrary.getTagPath(tr.getTagDefinition()), tr.getTagInstance()); } } return null; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } UserMarkupCollection other = (UserMarkupCollection) obj; if (id == null) { if (other.id != null) { return false; } } else if (!id.equals(other.id)) { return false; } return true; } public AccessMode getAccessMode() { return accessMode; } }