package com.bagri.core.model; import java.util.Arrays; import java.util.BitSet; import java.util.Date; import java.util.HashMap; import java.util.Map; import com.bagri.core.Convertable; import com.bagri.core.Versionable; import static com.bagri.core.DocumentKey.*; import static com.bagri.support.util.FileUtils.def_encoding; /** * Represents XDM document instance: container for XDM elements. * * @author Denis Sukhoroslov * @since 05.2013 */ public class Document implements Comparable<Document>, Convertable<Map<String, Object>>, Versionable { public static final int dvFirst = 1; public static final int clnDefault = -1; private long documentKey; private String uri; private String root; private String encoding; private long txStart; private long txFinish; private long createdAt; private String createdBy; private int bytes; private int elements; private BitSet collections = new BitSet(8); /** * default constructor */ public Document() { // } /** * * @param docKey the internal document's key * @param uri the document's uri * @param root the document's type root * @param owner the document's owner * @param txId the transaction id created the document * @param bytes the size of document in bytes * @param elts the size of document in elements */ public Document(long docKey, String uri, String root, String owner, long txId, int bytes, int elts) { this(docKey, uri, root, txId, 0, new Date(), owner, def_encoding, bytes, elts); } /** * * @param docKey the internal document's key * @param uri the document's uri * @param root the document's type root * @param txStart the transaction id created the document * @param txFinish the transaction id finished the document * @param createdAt the date/time when the document was created * @param createdBy the document's owner * @param encoding the document's encoding * @param bytes the size of document in bytes * @param elts the size of document in elements */ public Document(long docKey, String uri, String root, long txStart, long txFinish, Date createdAt, String createdBy, String encoding, int bytes, int elts) { this.documentKey = docKey; //toKey(hash, revision, version); this.uri = uri; this.root = root; this.txStart = txStart; this.txFinish = txFinish; this.createdAt = createdAt.getTime(); this.createdBy = createdBy.intern(); this.encoding = encoding.intern(); this.bytes = bytes; this.elements = elts; } /** * @return the document key */ public long getDocumentKey() { return documentKey; } /** * @return the document size in bytes */ public int getBytes() { return bytes; } /** * @return the number of elements belonging to document */ public int getElements() { return elements; } /** * @return the document version */ public int getVersion() { return toVersion(documentKey); } /** * @return the document's uri */ public String getUri() { return uri; } /** * @return the document's type id */ public String getTypeRoot() { return root; } /** * @return the document's encoding */ public String getEncoding() { return encoding; } /** * @return initiated transaction id */ public long getTxStart() { return txStart; } /** * @return finalized transaction id */ public long getTxFinish() { return txFinish; } /** * @return the date/time when the document was created */ @Override public Date getCreatedAt() { return new Date(createdAt); } /** * @return the user who has created the document */ @Override public String getCreatedBy() { return createdBy; } /** * * @return the number of fragments owning by the documents. A single document has 1 fragment */ public long[] getFragments() { return new long[] {documentKey}; } /** * @param by the user who has updated the document */ @Override public void updateVersion(String by) { documentKey++; createdAt = System.currentTimeMillis(); createdBy = by; } /** * * @param txFinish set document's finalizing transaction id */ public void finishDocument(long txFinish) { //, String by) { this.txFinish = txFinish; //updateVersion(by); } /** * * @return ids of document collections */ public int[] getCollections() { // may be we should cache it?? int[] result = new int[collections.cardinality()]; int idx = 0; for (int i = collections.nextSetBit(0); i >= 0; i = collections.nextSetBit(i+1)) { result[idx++] = i; } return result; } /** * * @param collectId the collection id * @return true if document is included in the collection, false otherwise */ public boolean hasCollection(int collectId) { if (collectId < 0) return false; return collections.get(collectId); } /** * * @param collectId adds document to collection * @return true if document was added, false otherwise */ public boolean addCollection(int collectId) { if (!collections.get(collectId)) { collections.set(collectId); return true; } return false; } /** * * @param collectId removes document from collection * @return true if document was removed, false otherwise */ public boolean removeCollection(int collectId) { //if (collectId == XDMCollection.clDocType) { // return false; // we never remove default docType collection //} if (collections.get(collectId)) { collections.clear(collectId); return true; } return false; } /** * * @param collections set document collections */ public void setCollections(int[] collections) { this.collections.clear(); if (collections != null) { for (int i=0; i < collections.length; i++) { this.collections.set(collections[i]); } } } /** * @return Map representation of the document */ @Override public Map<String, Object> convert() { Map<String, Object> result = new HashMap<>(); result.put("key", documentKey); result.put("version", getVersion()); result.put("uri", uri); result.put("bytes", bytes); result.put("elements", elements); result.put("root", root); result.put("encoding", encoding); result.put("txStart", txStart); result.put("txFinish", txFinish); result.put("created at", getCreatedAt().toString()); result.put("created by", createdBy); result.put("fragments", getFragments().length); result.put("collections", Arrays.toString(getCollections())); return result; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "Document [key=" + documentKey + ", version=" + getVersion() + ", uri=" + uri + ", root=" + root + ", createdAt=" + getCreatedAt() + ", createdBy=" + createdBy + ", encoding=" + encoding + ", bytes=" + bytes + ", txStart=" + txStart + ", txFinish=" + txFinish + ", elements=" + elements + ", number of fragments=" + getFragments().length + ", collections=" + Arrays.toString(getCollections()) + "]"; } @Override public int compareTo(Document other) { int result = this.uri.compareTo(other.uri); if (result == 0) { result = this.getVersion() - other.getVersion(); } return result; } }