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 * bstefanescu 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.rendering.api; 023 024import java.util.ArrayList; 025import java.util.Arrays; 026import java.util.Calendar; 027import java.util.Collection; 028import java.util.HashMap; 029import java.util.Map; 030 031import org.nuxeo.ecm.core.api.Blob; 032import org.nuxeo.ecm.core.api.Blobs; 033import org.nuxeo.ecm.core.api.CoreSession; 034import org.nuxeo.ecm.core.api.DocumentModel; 035import org.nuxeo.ecm.core.api.PropertyException; 036import org.nuxeo.ecm.core.api.model.PropertyNotFoundException; 037import org.nuxeo.ecm.core.schema.FacetNames; 038import org.nuxeo.ecm.platform.rendering.fm.adapters.SchemaTemplate; 039 040/** 041 * Base class to build views for Document oriented contexts (contexts that are bound to a document). 042 * <p> 043 * Note that this class cannot be used with contexts for which the {@link RenderingContext#getDocument()} method is 044 * returning null. 045 * <p> 046 * This implementation ensure that the context argument is never used so it can be used outside the scope of a rendering 047 * context to get a view over the document. 048 * 049 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 050 */ 051public class DefaultDocumentView implements DocumentView { 052 053 // Must be returned by get() method when the key is unknown since the caller 054 // should be able to 055 // treat differently a key hit that returned null from a key that is not 056 // known by this view 057 public static final Object UNKNOWN = new Object(); 058 059 public interface Field { 060 String getName(); 061 062 Object getValue(DocumentModel doc); 063 } 064 065 protected final Map<String, Field> fields; 066 067 public DefaultDocumentView() { 068 fields = new HashMap<String, Field>(); 069 initialize(); 070 } 071 072 public DefaultDocumentView(Map<String, Field> fields) { 073 this.fields = fields == null ? new HashMap<String, Field>() : fields; 074 } 075 076 protected void initialize() { 077 addField(SESSION); 078 079 addField(ID); 080 addField(NAME); 081 addField(PATH); 082 addField(TYPE); 083 addField(SID); 084 addField(REPOSITORY); 085 086 addField(SCHEMAS); 087 addField(FACETS); 088 addField(LOCKED); 089 addField(LIFE_CYCLE_STATE); 090 addField(LIFE_CYCLE_POLICY); 091 addField(ALLOWED_STATE_TRANSITIONS); 092 addField(IS_FOLDER); 093 addField(TITLE); 094 addField(AUTHOR); 095 addField(CREATED); 096 addField(MODIFIED); 097 addField(CONTENT); 098 099 addField(PARENT); 100 addField(CHILDREN); 101 addField(REF); 102 addField(VERSIONS); 103 addField(PROXIES); 104 addField(VERSION_LABEL); 105 addField(SOURCE_ID); 106 } 107 108 public final void addField(Field field) { 109 fields.put(field.getName(), field); 110 } 111 112 public final void addFields(Collection<Field> fields) { 113 for (Field field : fields) { 114 this.fields.put(field.getName(), field); 115 } 116 } 117 118 public final void removeField(String name) { 119 fields.remove(name); 120 } 121 122 public Field getField(String name) { 123 return fields.get(name); 124 } 125 126 public Object get(DocumentModel doc, String name) throws PropertyException { 127 Field field = fields.get(name); 128 if (field != null) { 129 return field.getValue(doc); 130 } 131 // may be a a property xpath 132 if (name.indexOf(':') > -1) { 133 return doc.getProperty(name); 134 } 135 // may be a schema name 136 if (doc.hasSchema(name)) { 137 return new SchemaTemplate.DocumentSchema(doc, name); 138 } 139 return UNKNOWN; 140 } 141 142 public Collection<String> keys(DocumentModel doc) { 143 Collection<String> keys = new ArrayList<String>(fields.keySet()); 144 keys.addAll(Arrays.asList(doc.getSchemas())); 145 return keys; 146 } 147 148 public Map<String, Field> getFields() { 149 return fields; 150 } 151 152 public boolean isEmpty() { 153 return fields.isEmpty(); 154 } 155 156 public int size(DocumentModel doc) { 157 return fields.size() + doc.getSchemas().length; 158 } 159 160 protected static final Field SESSION = new Field() { 161 public final String getName() { 162 return "session"; 163 } 164 165 public Object getValue(DocumentModel doc) { 166 return doc.getCoreSession(); 167 } 168 }; 169 170 protected static final Field ID = new Field() { 171 public final String getName() { 172 return "id"; 173 } 174 175 public Object getValue(DocumentModel doc) { 176 return doc.getId(); 177 } 178 }; 179 180 protected static final Field NAME = new Field() { 181 public final String getName() { 182 return "name"; 183 } 184 185 public Object getValue(DocumentModel doc) { 186 return doc.getName(); 187 } 188 }; 189 190 protected static final Field PATH = new Field() { 191 public final String getName() { 192 return "path"; 193 } 194 195 public Object getValue(DocumentModel doc) { 196 return doc.getPathAsString(); 197 } 198 }; 199 200 protected static final Field TYPE = new Field() { 201 public final String getName() { 202 return "type"; 203 } 204 205 public Object getValue(DocumentModel doc) { 206 return doc.getType(); 207 } 208 }; 209 210 protected static final Field SCHEMAS = new Field() { 211 public final String getName() { 212 return "schemas"; 213 } 214 215 public Object getValue(DocumentModel doc) { 216 return doc.getSchemas(); 217 } 218 }; 219 220 protected static final Field FACETS = new Field() { 221 public final String getName() { 222 return "facets"; 223 } 224 225 public Object getValue(DocumentModel doc) { 226 return doc.getFacets(); 227 } 228 }; 229 230 protected static final Field STATE = new Field() { 231 public final String getName() { 232 return "state"; 233 } 234 235 public Object getValue(DocumentModel doc) { 236 return doc.getCurrentLifeCycleState(); 237 } 238 }; 239 240 protected static final Field LOCKED = new Field() { 241 public final String getName() { 242 return "isLocked"; 243 } 244 245 public Object getValue(DocumentModel doc) { 246 return doc.isLocked(); 247 } 248 }; 249 250 protected static final Field LIFE_CYCLE_STATE = new Field() { 251 public final String getName() { 252 return "lifeCycleState"; 253 } 254 255 public Object getValue(DocumentModel doc) { 256 return doc.getCurrentLifeCycleState(); 257 } 258 }; 259 260 protected static final Field LIFE_CYCLE_POLICY = new Field() { 261 public final String getName() { 262 return "lifeCyclePolicy"; 263 } 264 265 public Object getValue(DocumentModel doc) { 266 return doc.getLifeCyclePolicy(); 267 } 268 }; 269 270 protected static final Field ALLOWED_STATE_TRANSITIONS = new Field() { 271 public final String getName() { 272 return "allowedStateTransitions"; 273 } 274 275 public Object getValue(DocumentModel doc) { 276 return doc.getAllowedStateTransitions(); 277 } 278 }; 279 280 protected static final Field IS_FOLDER = new Field() { 281 public final String getName() { 282 return "isFolder"; 283 } 284 285 public Object getValue(DocumentModel doc) { 286 return doc.getFacets().contains(FacetNames.FOLDERISH); 287 } 288 }; 289 290 protected static final Field TITLE = new Field() { 291 public String getName() { 292 return "title"; 293 } 294 295 public Object getValue(DocumentModel doc) { 296 return doc.getTitle(); 297 } 298 }; 299 300 protected static final Field AUTHOR = new Field() { 301 public String getName() { 302 return "author"; 303 } 304 305 public Object getValue(DocumentModel doc) { 306 try { 307 return doc.getPropertyValue("dc:creator"); 308 } catch (PropertyNotFoundException e) { 309 // ignore 310 } 311 return null; 312 } 313 }; 314 315 protected static final Field CREATED = new Field() { 316 public String getName() { 317 return "created"; 318 } 319 320 public Object getValue(DocumentModel doc) { 321 try { 322 Calendar cal = (Calendar) doc.getPropertyValue("dc:created"); 323 if (cal != null) { 324 return cal.getTime(); 325 } 326 } catch (PropertyNotFoundException e) { 327 // ignore 328 } 329 return null; 330 } 331 }; 332 333 protected static final Field MODIFIED = new Field() { 334 public String getName() { 335 return "modified"; 336 } 337 338 public Object getValue(DocumentModel doc) { 339 try { 340 Calendar cal = (Calendar) doc.getPropertyValue("dc:modified"); 341 if (cal != null) { 342 return cal.getTime(); 343 } 344 } catch (PropertyNotFoundException e) { 345 // ignore 346 } 347 return null; 348 } 349 }; 350 351 protected static final Field CONTENT = new Field() { 352 public String getName() { 353 return "content"; 354 } 355 356 public Object getValue(DocumentModel doc) { 357 try { 358 Blob blob = (Blob) doc.getPropertyValue("file:content"); 359 if (blob != null) { 360 return blob; 361 } 362 } catch (PropertyNotFoundException e) { 363 // ignore 364 } 365 return Blobs.createBlob(""); 366 } 367 }; 368 369 protected static final Field SID = new Field() { 370 public String getName() { 371 return "sessionId"; 372 } 373 374 public Object getValue(DocumentModel doc) { 375 return doc.getSessionId(); 376 } 377 }; 378 379 protected static final Field REPOSITORY = new Field() { 380 public String getName() { 381 return "repository"; 382 } 383 384 public Object getValue(DocumentModel doc) { 385 return doc.getRepositoryName(); 386 } 387 }; 388 389 protected static final Field PARENT = new Field() { 390 public String getName() { 391 return "parent"; 392 } 393 394 public Object getValue(DocumentModel doc) { 395 CoreSession session = doc.getCoreSession(); 396 return session.getParentDocument(doc.getRef()); 397 } 398 }; 399 400 protected static final Field CHILDREN = new Field() { 401 public String getName() { 402 return "children"; 403 } 404 405 public Object getValue(DocumentModel doc) { 406 CoreSession session = doc.getCoreSession(); 407 return session.getChildren(doc.getRef()); 408 } 409 }; 410 411 protected static final Field REF = new Field() { 412 public String getName() { 413 return "ref"; 414 } 415 416 public Object getValue(DocumentModel doc) { 417 return doc.getRef(); 418 } 419 }; 420 421 protected static final Field VERSIONS = new Field() { 422 public String getName() { 423 return "versions"; 424 } 425 426 public Object getValue(DocumentModel doc) { 427 CoreSession session = doc.getCoreSession(); 428 return session.getVersions(doc.getRef()); 429 } 430 }; 431 432 protected static final Field PROXIES = new Field() { 433 public String getName() { 434 return "proxies"; 435 } 436 437 public Object getValue(DocumentModel doc) { 438 CoreSession session = doc.getCoreSession(); 439 return session.getProxies(doc.getRef(), null); 440 } 441 }; 442 443 protected static final Field VERSION_LABEL = new Field() { 444 public String getName() { 445 return "versionLabel"; 446 } 447 448 public Object getValue(DocumentModel doc) { 449 return doc.getVersionLabel(); 450 } 451 }; 452 453 protected static final Field SOURCE_ID = new Field() { 454 public String getName() { 455 return "sourceId"; 456 } 457 458 public Object getValue(DocumentModel doc) { 459 return doc.getSourceId(); 460 } 461 }; 462 463 /** 464 * The singleton instance that should be used by clients. Warn that this static field must be defined at the end of 465 * the class after any other field class since it will try to register these fields (otherwise fields will not be 466 * defined yet at the time of the initialization of that static member 467 */ 468 public static final DefaultDocumentView DEFAULT = new DefaultDocumentView(); 469 470}