001/*
002 * (C) Copyright 2016 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bdelbosc
018 */
019package org.nuxeo.ecm.platform.importer.mqueues.message;
020
021import org.nuxeo.ecm.core.api.Blob;
022import org.nuxeo.ecm.core.blob.BlobManager;
023
024import java.io.IOException;
025import java.io.ObjectInput;
026import java.io.ObjectOutput;
027import java.io.Serializable;
028import java.util.Collections;
029import java.util.HashMap;
030import java.util.Map;
031
032/**
033 * Message that represent an immutable Nuxeo document.
034 *
035 * @since 9.1
036 */
037public class DocumentMessage implements Message {
038    private String type;
039    private String parentPath;
040    private String name;
041    private Map<String, Serializable> properties;
042    private Blob blob;
043    private BlobManager.BlobInfo blobInfo;
044
045    private DocumentMessage(Builder builder) {
046        type = builder.type;
047        parentPath = builder.parentPath;
048        name = builder.name;
049        properties = builder.properties;
050        blob = builder.blob;
051        blobInfo = builder.blobInfo;
052    }
053
054    public String getName() {
055        return name;
056    }
057
058    @Override
059    public String getId() {
060        return parentPath + "/" + name;
061    }
062
063    /**
064     * Type of the document
065     */
066    public String getType() {
067        return type;
068    }
069
070    public String getParentPath() {
071        return parentPath;
072    }
073
074    public Map<String, Serializable> getProperties() {
075        return Collections.unmodifiableMap(properties);
076    }
077
078    public Blob getBlob() {
079        // TODO should return unmodifialble blob
080        return blob;
081    }
082
083    public BlobManager.BlobInfo getBlobInfo() {
084        return blobInfo;
085    }
086
087    /**
088     * Helper to build a document message.
089     *
090     * @param type the type of document
091     * @param parentPath the container path where the document should be created
092     * @param name the name of the document
093     */
094    public static Builder builder(String type, String parentPath, String name) {
095        return new Builder(type, parentPath, name);
096    }
097
098    public static class Builder {
099        private final String name;
100        private final String parentPath;
101        private final String type;
102        private Map<String, Serializable> properties;
103        private Blob blob;
104        private BlobManager.BlobInfo blobInfo;
105
106        protected Builder(String type, String parentPath, String name) {
107            this.type = type;
108            this.parentPath = parentPath;
109            this.name = name;
110        }
111
112        @SuppressWarnings("unchecked")
113        public Builder setProperties(HashMap<String, Serializable> properties) {
114            this.properties = (Map) properties.clone();
115            return this;
116        }
117
118        public Builder setBlob(Blob blob) {
119            this.blob = blob;
120            return this;
121        }
122
123        public Builder setBlobInfo(BlobManager.BlobInfo blobInfo) {
124            this.blobInfo = new BlobManager.BlobInfo(blobInfo);
125            return this;
126        }
127
128        public String getName() {
129            return name;
130        }
131
132        public String getParentPath() {
133            return parentPath;
134        }
135
136        public String getType() {
137            return type;
138        }
139
140        public Map<String, Serializable> getProperties() {
141            return properties;
142        }
143
144        public DocumentMessage build() {
145            return new DocumentMessage(this);
146        }
147    }
148
149    @Override
150    public void writeExternal(ObjectOutput out) throws IOException {
151        out.writeObject(type);
152        out.writeObject(parentPath);
153        out.writeObject(name);
154        int nbProperties = (properties == null ? 0 : properties.size());
155        out.writeInt(nbProperties);
156        if (properties != null) {
157            for (Map.Entry<String, Serializable> entry : properties.entrySet()) {
158                out.writeObject(entry.getKey());
159                out.writeObject(entry.getValue());
160            }
161        }
162        if (blob != null) {
163            out.writeBoolean(true);
164            out.writeObject(blob);
165        } else {
166            out.writeBoolean(false);
167        }
168        if (blobInfo != null) {
169            out.writeBoolean(true);
170            out.writeObject(blobInfo.key);
171            out.writeObject(blobInfo.digest);
172            out.writeLong(blobInfo.length);
173            out.writeObject(blobInfo.filename);
174            out.writeObject(blobInfo.encoding);
175            out.writeObject(blobInfo.mimeType);
176        } else {
177            out.writeBoolean(false);
178        }
179    }
180
181    @Override
182    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
183        type = (String) in.readObject();
184        parentPath = (String) in.readObject();
185        name = (String) in.readObject();
186        int nbProperties = in.readInt();
187        if (nbProperties > 0) {
188            properties = new HashMap<>(nbProperties);
189            while (nbProperties > 0) {
190                String key = (String) in.readObject();
191                Serializable value = (Serializable) in.readObject();
192                properties.put(key, value);
193                nbProperties--;
194            }
195        }
196        if (in.readBoolean()) {
197            blob = (Blob) in.readObject();
198        }
199        if (in.readBoolean()) {
200            blobInfo = new BlobManager.BlobInfo();
201            blobInfo.key = (String) in.readObject();
202            blobInfo.digest = (String) in.readObject();
203            blobInfo.length = in.readLong();
204            blobInfo.filename = (String) in.readObject();
205            blobInfo.encoding = (String) in.readObject();
206            blobInfo.mimeType = (String) in.readObject();
207        }
208
209    }
210
211    @Override
212    public String toString() {
213        String bi = "";
214        if (blobInfo != null) {
215            bi = String.format("blobInfo(key=%s filename=%s)", blobInfo.key, blobInfo.filename);
216        } else if (blob != null) {
217            bi = String.format("blob(filename=%s)", blob.getFilename());
218        }
219        return String.format("DocumentMessage(type=%s name=%s parentPath=%s bi=%s)", type, name, parentPath, bi);
220    }
221//TODO: impl hashCode, equals, toString
222}
223