001/* 002 * (C) Copyright 2006-2011 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 * matic 018 */ 019package org.nuxeo.ecm.automation.client.jaxrs.spi.marshallers; 020 021import java.io.IOException; 022 023import org.nuxeo.ecm.automation.client.jaxrs.spi.JsonMarshaller; 024import org.nuxeo.ecm.automation.client.model.Document; 025import org.nuxeo.ecm.automation.client.model.PropertyList; 026import org.nuxeo.ecm.automation.client.model.PropertyMap; 027import org.nuxeo.ecm.automation.client.model.PropertyMapSetter; 028 029import com.fasterxml.jackson.core.JsonGenerator; 030import com.fasterxml.jackson.core.JsonParser; 031import com.fasterxml.jackson.core.JsonToken; 032 033/** 034 * @author matic 035 */ 036public class DocumentMarshaller implements JsonMarshaller<Document> { 037 038 @Override 039 public String getType() { 040 return "document"; 041 } 042 043 @Override 044 public Class<Document> getJavaType() { 045 return Document.class; 046 } 047 048 @Override 049 public Document read(JsonParser jp) throws IOException { 050 return readDocument(jp); 051 } 052 053 protected static Document readDocument(JsonParser jp) throws IOException { 054 String uid = null; 055 String type = null; 056 String path = null; 057 String state = null; 058 String versionLabel = null; 059 String isCheckedOut = null; 060 String lockCreated = null; 061 String lockOwner = null; 062 String repository = null; 063 PropertyList facets = null; 064 String changeToken = null; 065 JsonToken tok = jp.nextToken(); 066 PropertyMap props = new PropertyMap(); 067 PropertyMapSetter propsSetter = new PropertyMapSetter(props); 068 PropertyMap contextParameters = new PropertyMap(); 069 while (tok != null && tok != JsonToken.END_OBJECT) { 070 String key = jp.getCurrentName(); 071 tok = jp.nextToken(); 072 if (key.equals("uid")) { 073 uid = jp.getText(); 074 } else if (key.equals("path")) { 075 path = jp.getText(); 076 } else if (key.equals("type")) { 077 type = jp.getText(); 078 } else if (key.equals("state")) { 079 state = jp.getText(); 080 } else if (key.equals("versionLabel")) { 081 versionLabel = jp.getText(); 082 } else if (key.equals("isCheckedOut")) { 083 isCheckedOut = jp.getText(); 084 } else if (key.equals("lock")) { 085 if (!JsonToken.VALUE_NULL.equals(jp.getCurrentToken())) { 086 String[] lock = jp.getText().split(":"); 087 lockOwner = lock[0]; 088 lockCreated = lock[1]; 089 } 090 } else if (key.equals("lockCreated")) { 091 lockCreated = jp.getText(); 092 } else if (key.equals("lockOwner")) { 093 lockOwner = jp.getText(); 094 } else if (key.equals("repository")) { 095 repository = jp.getText(); 096 } else if (key.equals("title")) { 097 propsSetter.set("dc:title", jp.getText()); 098 } else if (key.equals("lastModified")) { 099 propsSetter.set("dc:modified", jp.getText()); 100 } else if (key.equals("properties")) { 101 readProperties(jp, props); 102 } else if (key.equals("facets")) { 103 facets = readArrayProperty(jp); 104 } else if (key.equals("changeToken")) { 105 changeToken = jp.getText(); 106 } else if (key.equals("contextParameters")) { 107 readProperties(jp, contextParameters); 108 } else { 109 // do skip unknown keys 110 jp.skipChildren(); 111 } 112 tok = jp.nextToken(); 113 } 114 if (tok == null) { 115 throw new IllegalArgumentException("Unexpected end of stream."); 116 } 117 return new Document(uid, type, facets, changeToken, path, state, lockOwner, lockCreated, repository, 118 versionLabel, isCheckedOut, props, contextParameters); 119 } 120 121 protected static void readProperties(JsonParser jp, PropertyMap props) throws IOException { 122 PropertyMapSetter setter = new PropertyMapSetter(props); 123 JsonToken tok = jp.nextToken(); 124 while (tok != null && tok != JsonToken.END_OBJECT) { 125 String key = jp.getCurrentName(); 126 tok = jp.nextToken(); 127 if (tok == JsonToken.START_ARRAY) { 128 setter.set(key, readArrayProperty(jp)); 129 } else if (tok == JsonToken.START_OBJECT) { 130 setter.set(key, readObjectProperty(jp)); 131 } else if (tok == JsonToken.VALUE_NULL) { 132 setter.set(key, (String) null); 133 } else { 134 setter.set(key, jp.getText()); 135 } 136 tok = jp.nextToken(); 137 } 138 if (tok == null) { 139 throw new IllegalArgumentException("Unexpected end of stream."); 140 } 141 } 142 143 protected static PropertyMap readObjectProperty(JsonParser jp) throws IOException { 144 PropertyMap map = new PropertyMap(); 145 readProperties(jp, map); 146 return map; 147 } 148 149 protected static PropertyList readArrayProperty(JsonParser jp) throws IOException { 150 PropertyList list = new PropertyList(); 151 JsonToken tok = jp.nextToken(); 152 while (tok != JsonToken.END_ARRAY) { 153 if (tok == JsonToken.START_ARRAY) { 154 list.add(readArrayProperty(jp)); 155 } else if (tok == JsonToken.START_OBJECT) { 156 list.add(readObjectProperty(jp)); 157 } else { 158 list.add(jp.getText()); 159 } 160 tok = jp.nextToken(); 161 } 162 return list; 163 } 164 165 @Override 166 public void write(JsonGenerator jg, Object value) throws IOException { 167 // TODO: extend the server json API to allow for document refs passed as 168 // JSON data-structures instead of the input ref microsyntax used by 169 throw new UnsupportedOperationException(); 170 } 171 172}