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