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.pattern.message;
020
021import org.nuxeo.ecm.core.api.Blob;
022import org.nuxeo.ecm.core.blob.BlobInfo;
023import org.nuxeo.ecm.platform.importer.mqueues.pattern.Message;
024
025import java.io.IOException;
026import java.io.ObjectInput;
027import java.io.ObjectOutput;
028import java.io.Serializable;
029import java.util.Collections;
030import java.util.HashMap;
031import java.util.Map;
032
033/**
034 * Message that represent an immutable Nuxeo document.
035 *
036 * @since 9.1
037 */
038public class DocumentMessage implements Message {
039    static final long serialVersionUID = 20170529L;
040    private String type;
041    private String parentPath;
042    private String name;
043    private Map<String, Serializable> properties;
044    private Blob blob;
045    private BlobInfo blobInfo;
046
047    public DocumentMessage() {
048    }
049
050    private DocumentMessage(Builder builder) {
051        type = builder.type;
052        parentPath = builder.parentPath;
053        name = builder.name;
054        properties = builder.properties;
055        blob = builder.blob;
056        blobInfo = builder.blobInfo;
057    }
058
059    public String getName() {
060        return name;
061    }
062
063    @Override
064    public String getId() {
065        return parentPath + "/" + name;
066    }
067
068    /**
069     * Type of the document
070     */
071    public String getType() {
072        return type;
073    }
074
075    public String getParentPath() {
076        return parentPath;
077    }
078
079    public Map<String, Serializable> getProperties() {
080        return Collections.unmodifiableMap(properties);
081    }
082
083    public Blob getBlob() {
084        // TODO should return unmodifiable blob
085        return blob;
086    }
087
088    public BlobInfo getBlobInfo() {
089        return blobInfo;
090    }
091
092    /**
093     * Helper to build a document message.
094     *
095     * @param type the type of document
096     * @param parentPath the container path where the document should be created
097     * @param name the name of the document
098     */
099    public static Builder builder(String type, String parentPath, String name) {
100        return new Builder(type, parentPath, name);
101    }
102
103    public static class Builder {
104        private final String name;
105        private final String parentPath;
106        private final String type;
107        private Map<String, Serializable> properties;
108        private Blob blob;
109        private BlobInfo blobInfo;
110
111        protected Builder(String type, String parentPath, String name) {
112            this.type = type;
113            this.parentPath = parentPath;
114            this.name = name;
115        }
116
117        @SuppressWarnings("unchecked")
118        public Builder setProperties(HashMap<String, Serializable> properties) {
119            this.properties = (Map) properties.clone();
120            return this;
121        }
122
123        public Builder setBlob(Blob blob) {
124            this.blob = blob;
125            return this;
126        }
127
128        public Builder setBlobInfo(BlobInfo blobInfo) {
129            this.blobInfo = new BlobInfo(blobInfo);
130            return this;
131        }
132
133        public String getName() {
134            return name;
135        }
136
137        public String getParentPath() {
138            return parentPath;
139        }
140
141        public String getType() {
142            return type;
143        }
144
145        public Map<String, Serializable> getProperties() {
146            return properties;
147        }
148
149        public DocumentMessage build() {
150            return new DocumentMessage(this);
151        }
152    }
153
154    @Override
155    public void writeExternal(ObjectOutput out) throws IOException {
156        out.writeObject(type);
157        out.writeObject(parentPath);
158        out.writeObject(name);
159        int nbProperties = (properties == null ? 0 : properties.size());
160        out.writeInt(nbProperties);
161        if (properties != null) {
162            for (Map.Entry<String, Serializable> entry : properties.entrySet()) {
163                out.writeObject(entry.getKey());
164                out.writeObject(entry.getValue());
165            }
166        }
167        if (blob != null) {
168            out.writeBoolean(true);
169            out.writeObject(blob);
170        } else {
171            out.writeBoolean(false);
172        }
173        if (blobInfo != null) {
174            out.writeBoolean(true);
175            out.writeObject(blobInfo.key);
176            out.writeObject(blobInfo.digest);
177            out.writeLong(blobInfo.length);
178            out.writeObject(blobInfo.filename);
179            out.writeObject(blobInfo.encoding);
180            out.writeObject(blobInfo.mimeType);
181        } else {
182            out.writeBoolean(false);
183        }
184    }
185
186    @Override
187    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
188        type = (String) in.readObject();
189        parentPath = (String) in.readObject();
190        name = (String) in.readObject();
191        int nbProperties = in.readInt();
192        if (nbProperties > 0) {
193            properties = new HashMap<>(nbProperties);
194            while (nbProperties > 0) {
195                String key = (String) in.readObject();
196                Serializable value = (Serializable) in.readObject();
197                properties.put(key, value);
198                nbProperties--;
199            }
200        }
201        if (in.readBoolean()) {
202            blob = (Blob) in.readObject();
203        }
204        if (in.readBoolean()) {
205            blobInfo = new BlobInfo();
206            blobInfo.key = (String) in.readObject();
207            blobInfo.digest = (String) in.readObject();
208            blobInfo.length = in.readLong();
209            blobInfo.filename = (String) in.readObject();
210            blobInfo.encoding = (String) in.readObject();
211            blobInfo.mimeType = (String) in.readObject();
212        }
213
214    }
215
216    @Override
217    public String toString() {
218        String bi = "";
219        if (blobInfo != null) {
220            bi = String.format("blobInfo(key=%s filename=%s)", blobInfo.key, blobInfo.filename);
221        } else if (blob != null) {
222            bi = String.format("blob(filename=%s)", blob.getFilename());
223        }
224        return String.format("DocumentMessage(type=%s name=%s parentPath=%s bi=%s)", type, name, parentPath, bi);
225    }
226//TODO: impl hashCode, equals, toString
227}
228