Java tutorial
/* * Sentilab SARE: a Sentiment Analysis Research Environment * Copyright (C) 2013 Sabanci University Sentilab * http://sentilab.sabanciuniv.edu * * This file is part of SARE. * * SARE 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. * * SARE 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 SARE. If not, see <http://www.gnu.org/licenses/>. */ package edu.sabanciuniv.sentilab.sare.models.base.documentStore; import java.util.*; import javax.persistence.*; import javax.persistence.criteria.*; import org.apache.commons.lang3.Validate; import com.google.common.collect.*; import edu.sabanciuniv.sentilab.sare.models.base.*; import edu.sabanciuniv.sentilab.sare.models.base.document.PersistentDocument; import edu.sabanciuniv.sentilab.utils.CannedMessages; /** * The base class for all objects that can store documents. * @author Mus'ab Husaini */ @Entity public abstract class PersistentDocumentStore extends PersistentObject implements DocumentStoreLike { /** * */ private static final long serialVersionUID = 24809167105583854L; @ManyToOne @JoinColumn(name = "base_store_id") private PersistentDocumentStore baseStore; @OneToMany(mappedBy = "baseStore") private Collection<PersistentDocumentStore> derivedStores; @Column(name = "owner_id") private String ownerId; /** * The documents stored under this store. Derived classes are responsible for maintaining this relationship. */ @OneToMany(mappedBy = "store") protected List<PersistentDocument> documents; protected PersistentDocumentStore addDerivedStore(PersistentDocumentStore derivedStore) { Validate.notNull(derivedStore, CannedMessages.NULL_ARGUMENT, "derivedStore"); if (!this.hasDerivedStore(derivedStore)) { this.derivedStores.add(derivedStore); } if (derivedStore.getBaseStore() != this) { derivedStore.setBaseStore(this); } return this; } protected boolean removeDerivedStore(PersistentDocumentStore derivedStore) { Validate.notNull(derivedStore, CannedMessages.NULL_ARGUMENT, "derivedStore"); boolean result = false; if (this.hasDerivedStore(derivedStore)) { result = this.derivedStores.remove(derivedStore); if (derivedStore.getBaseStore() == this) { derivedStore.setBaseStore(null); } } return result; } /** * Gets the base store for this store. * @return the {@link PersistentDocumentStore} object that is the base store for this store. */ public PersistentDocumentStore getBaseStore() { return baseStore; } /** * Sets the base store for this store. * @param baseStore the base store. * @return the {@code this} object. */ public PersistentDocumentStore setBaseStore(PersistentDocumentStore baseStore) { // make sure we don't end up with a cyclical tree. PersistentDocumentStore chainBase = baseStore; while (chainBase != null) { if (chainBase.getIdentifier().equals(this.getIdentifier())) { throw new IllegalArgumentException("derived document tree must be acyclic"); } chainBase = chainBase.getBaseStore(); } PersistentDocumentStore prevBase = this.getBaseStore(); this.baseStore = baseStore; this.addReference(baseStore); if (prevBase != null) { this.removeReference(prevBase); prevBase.removeDerivedStore(this); } if (this.baseStore != null && !this.baseStore.hasDerivedStore(this)) { this.baseStore.addDerivedStore(this); } return this; } /** * Gets the derived stores of this store. * @return the {@link Iterable} of {@link PersistentDocumentStore} objects that derive from this store. */ public Iterable<PersistentDocumentStore> getDerivedStores() { if (this.derivedStores == null) { this.derivedStores = Lists.newArrayList(); } return Collections.unmodifiableCollection(this.derivedStores); } /** * Gets a flag indicating whether the provided store is in the list of derived stores for this store. * @param derivedStore the {@link PersistentDocumentStore} object to look for. * @return {@code true} if the provided store is in the list of derived stores, {@code false} otherwise. */ public boolean hasDerivedStore(PersistentDocumentStore derivedStore) { return Iterables.contains(this.getDerivedStores(), derivedStore); } @Override public String getTitle() { return this.title; } /** * Sets the title of this store. * @param title the title of this store. * @return the {@code this} object. */ public PersistentDocumentStore setTitle(String title) { this.title = title; return this; } @Override public String getLanguage() { return this.getProperty("language", String.class); } /** * Sets the language that this store's documents are in. * @param language the language of this store. * @return the {@code this} object. */ public PersistentDocumentStore setLanguage(String language) { this.setProperty("language", language); return this; } @Override public String getDescription() { return this.getProperty("description", String.class); } /** * Sets the description of this store. * @param description the description of this store. * @return the {@code this} object. */ public PersistentDocumentStore setDescription(String description) { this.setProperty("description", description); return this; } /** * Sets the ID of the entity that owns this store. * @param ownerId the ID of the owner. * @return the {@code this} object. */ public PersistentDocumentStore setOwnerId(String ownerId) { this.ownerId = ownerId; return this; } @Override public String getOwnerId() { return this.ownerId; } @Override public Iterable<PersistentDocument> getDocuments() { // must not return null. if (this.documents == null) { return Lists.newArrayList(); } return Collections.unmodifiableList(this.documents); } /** * Gets documents of a given type. * @param ofType the type of documents to get. * @return an {@link Iterable} of {@code T} type documents. */ public <T> Iterable<T> getDocuments(Class<T> ofType) { return Iterables.filter(this.getDocuments(), ofType); } /** * Gets identifiers of documents in this store. * @param em the {@link EntityManager} to get the documents from. * @return an {@link Iterable} of document identifiers. */ public Iterable<byte[]> getDocumentIds(EntityManager em) { Validate.notNull(em, CannedMessages.NULL_ARGUMENT, "em"); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<byte[]> cq = cb.createQuery(byte[].class); Root<PersistentDocument> doc = cq.from(PersistentDocument.class); cq.multiselect(doc.get("id")) .where(cb.equal(doc.get("store"), cb.parameter(PersistentDocumentStore.class, "store"))); TypedQuery<byte[]> tq = em.createQuery(cq); tq.setParameter("store", this); return tq.getResultList(); } /** * Sets the documents in this store. * @param documents the {@link Iterable} of documents to set. * @return the {@code this} object. */ public <T extends PersistentDocument> PersistentDocumentStore setDocuments(Iterable<T> documents) { if (documents == null) { if (Iterables.size(this.getDocuments()) != 0) { List<PersistentDocument> tmpDocuments = Lists.newArrayList(this.getDocuments()); for (PersistentDocument document : tmpDocuments) { this.removeDocument(document); } } this.documents = null; } else { this.setDocuments(null); for (PersistentDocument document : documents) { this.addDocument(document); } } return this; } /** * Gets a boolean flag indicating whether the provided document is in this store or not. * @param document the {@code PersistentDocument} object to look for. * @return {@code true} if the document is contained in this store, {@code false} otherwise. */ public boolean hasDocument(PersistentDocument document) { return this.getDocuments() != null ? Iterables.contains(this.getDocuments(), document) : false; } /** * Adds a document to this store. * @param document the {@code PersistentDocument} object to add. * @return the {@code this} object. */ public PersistentDocumentStore addDocument(PersistentDocument document) { Validate.notNull(document, CannedMessages.NULL_ARGUMENT, "document"); if (this.documents == null) { this.documents = Lists.newArrayList(); } if (document.getStore() != this) { document.setStore(this); } if (!this.documents.contains(document)) { this.documents.add(document); } this.addReferer(document); return this; } /** * Adds all the given document to this store. * @param documents the {@link Iterable} of {@link PersistentDocument} objects to add. * @return the {@code this} object. */ public PersistentDocumentStore addDocuments(Iterable<? extends PersistentDocument> documents) { Validate.notNull(documents, CannedMessages.NULL_ARGUMENT, "documents"); for (PersistentDocument document : documents) { this.addDocument(document); } return this; } /** * Removes a document from this store. * @param document the {@code PersistentDocument} object to remove. * @return {@code true} if an element was removed as a result of this call. */ public boolean removeDocument(PersistentDocument document) { if (document == null) { return false; } if (document.getStore() == this) { document.setStore(null); } this.removeReferer(document); if (this.documents == null) { return false; } if (this.documents.contains(document)) { return this.documents.remove(document); } else { return false; } } /** * Removes all the given documents from this store. * @param documents the {@link Iterable} of {@link PersistentDocument} objects to remove. * @return the {@code this} object. */ public PersistentDocumentStore removeDocuments(Iterable<? extends PersistentDocument> documents) { Validate.notNull(documents, CannedMessages.NULL_ARGUMENT, "documents"); for (PersistentDocument document : documents) { this.removeDocument(document); } return this; } }