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 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.common.xmap; 023 024import java.io.IOException; 025 026import org.nuxeo.common.xmap.annotation.XContent; 027import org.w3c.dom.DocumentFragment; 028import org.w3c.dom.Element; 029import org.w3c.dom.Node; 030import org.w3c.dom.ranges.DocumentRange; 031import org.w3c.dom.ranges.Range; 032 033import org.apache.xml.serialize.OutputFormat; 034 035/** 036 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 037 */ 038public class XAnnotatedContent extends XAnnotatedMember { 039 040 private static final OutputFormat DEFAULT_FORMAT = new OutputFormat(); 041 042 static { 043 DEFAULT_FORMAT.setOmitXMLDeclaration(true); 044 DEFAULT_FORMAT.setIndenting(true); 045 DEFAULT_FORMAT.setMethod("xml"); 046 DEFAULT_FORMAT.setEncoding("UTF-8"); 047 } 048 049 public XAnnotatedContent(XMap xmap, XAccessor setter, XContent anno) { 050 super(xmap, setter); 051 path = new Path(anno.value()); 052 type = setter.getType(); 053 valueFactory = xmap.getValueFactory(type); 054 xao = xmap.register(type); 055 } 056 057 @Override 058 protected Object getValue(Context ctx, Element base) { 059 Element el = (Element) DOMHelper.getElementNode(base, path); 060 if (el == null) { 061 return null; 062 } 063 el.normalize(); 064 Node node = el.getFirstChild(); 065 if (node == null) { 066 boolean asDOM = accessor.getType() == DocumentFragment.class; 067 return asDOM ? null : ""; 068 } 069 Range range = ((DocumentRange) el.getOwnerDocument()).createRange(); 070 range.setStartBefore(node); 071 range.setEndAfter(el.getLastChild()); 072 DocumentFragment fragment = range.cloneContents(); 073 boolean asDOM = accessor.getType() == DocumentFragment.class; 074 if (asDOM) { 075 return fragment; 076 } else { 077 try { 078 return DOMSerializer.toString(fragment, DEFAULT_FORMAT); 079 } catch (IOException e) { 080 throw new IllegalArgumentException(e); 081 } 082 } 083 } 084 085 @Override 086 public void toXML(Object instance, Element parent) { 087 Object v = accessor.getValue(instance); 088 if (v instanceof DocumentFragment) { 089 Element e = XMLBuilder.getOrCreateElement(parent, path); 090 DocumentFragment df = (DocumentFragment) v; 091 Node node = e.getOwnerDocument().importNode(df, true); 092 e.appendChild(node); 093 } else if (valueFactory != null && v != null) { 094 String value = valueFactory.serialize(null, v); 095 if (value != null) { 096 Element e = XMLBuilder.getOrCreateElement(parent, path); 097 DOMHelper.loadFragment(e, value); 098 } 099 } 100 } 101 102}