/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.riotfamily.components.xstream;
import java.io.StringReader;
import java.io.StringWriter;
import org.riotfamily.components.model.Component;
import org.riotfamily.components.model.ComponentList;
import org.riotfamily.components.model.Content;
import org.riotfamily.components.model.ContentMap;
import org.riotfamily.components.model.ContentMapImpl;
import org.riotfamily.components.model.ContentMapMarshaller;
import org.riotfamily.pages.model.VirtualPage;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.DataHolder;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.Mapper;
import com.thoughtworks.xstream.mapper.MapperWrapper;
public class XStreamMarshaller implements ContentMapMarshaller,
InitializingBean, ApplicationContextAware {
private XStream xstream;
private HierarchicalStreamDriver driver;
private ApplicationContext applicationContext;
public void setDriver(HierarchicalStreamDriver driver) {
this.driver = driver;
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void afterPropertiesSet() throws Exception {
if (driver == null) {
driver = new DomDriver("UTF-8");
}
xstream = new XStream(driver) {
@Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new HibernateProxyMapper(next);
}
};
xstream.alias("component", Component.class);
xstream.alias("component-list", ComponentList.class);
xstream.alias("content-map", ContentMapImpl.class);
xstream.alias("virtual-page", VirtualPage.class);
Mapper mapper = xstream.getMapper();
xstream.registerConverter(new HibernateEntityConverter(mapper,
applicationContext), 1);
xstream.registerConverter(new ComponentListConverter(mapper), 1);
xstream.registerConverter(new ComponentConverter(mapper), 2);
xstream.registerConverter(new ContentMapConverter(mapper), 1);
xstream.registerConverter(new VirtualPageConverter(), 1);
xstream.setMarshallingStrategy(new NullSafeXPathMarshallingStrategy());
}
private DataHolder createDataHolder(Content content) {
DataHolder dataHolder = xstream.newDataHolder();
dataHolder.put("content", content);
return dataHolder;
}
public ContentMap unmarshal(Content owner, String xml) {
HierarchicalStreamReader reader = driver.createReader(new StringReader(
xml));
return (ContentMap) xstream.unmarshal(reader, null,
createDataHolder(owner));
}
public String marshal(ContentMap contentMap) {
Content owner = contentMap.getContent();
StringWriter sw = new StringWriter();
HierarchicalStreamWriter writer = driver.createWriter(sw);
xstream.marshal(contentMap, writer, createDataHolder(owner));
return sw.toString();
}
public static void addReference(DataHolder dataHolder, Object ref) {
Content content = (Content) dataHolder.get("content");
content.addReference(ref);
}
}