/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.content;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import com.enonic.cms.framework.xml.IllegalCharacterCleaner;
import com.enonic.cms.framework.xml.XMLDocument;
import com.enonic.cms.framework.xml.XMLDocumentFactory;
import com.enonic.cms.core.content.index.ContentIndexConstants;
import com.enonic.cms.core.search.ContentIndexedFields;
import com.enonic.cms.core.search.query.ContentIndexService;
/**
* This class is used for admin to build xml for extended info such as index values and content data.
*/
public final class ContentSourceXmlCreator
implements ContentIndexConstants
{
private IllegalCharacterCleaner xmlCleaner = new IllegalCharacterCleaner();
private final ContentIndexService contentIndexService;
public ContentSourceXmlCreator( ContentIndexService contentIndexService )
{
this.contentIndexService = contentIndexService;
}
public XMLDocument createSourceDocument( ContentVersionEntity version )
{
Element root = new Element( "source" );
addContentDataElem( root, version );
addRelatedChildrenElem( root, version );
if ( version.getKey().equals( version.getContent().getMainVersion().getKey() ) )
{
// list only indexes when version is the main version
addIndexesElem( root, version.getContent().getKey() );
}
return XMLDocumentFactory.create( new Document( root ) );
}
private void addContentDataElem( Element parent, ContentVersionEntity version )
{
Element elem = new Element( "data" );
elem.setText( serializeDocument( version.getContentDataAsJDomDocument() ) );
parent.addContent( elem );
}
private void addIndexesElem( Element parent, ContentKey key )
{
Element elem = new Element( "indexes" );
parent.addContent( elem );
for ( Map.Entry<String, List<String>> entry : getIndexValues( key ).entrySet() )
{
elem.addContent( createIndexElem( entry.getKey(), entry.getValue() ) );
}
}
private void addRelatedChildrenElem( Element parent, ContentVersionEntity version )
{
Element childrenEl = new Element( "related-children" );
parent.addContent( childrenEl );
for ( ContentEntity child : version.getRelatedChildren( true ) )
{
childrenEl.addContent( createRelatedChildElem( child ) );
}
}
private Element createRelatedChildElem( ContentEntity child )
{
Element childEl = new Element( "content" );
childEl.setAttribute( "key", child.getKey().toString() );
childEl.setAttribute( "deleted", Boolean.toString( child.isDeleted() ) );
childEl.addContent( new Element( "repositorypath" ).setText( child.getPathAsString() ) );
childEl.addContent( new Element( "title" ).setText( child.getMainVersion().getTitle() ) );
return childEl;
}
private Element createIndexElem( String name, List<String> values )
{
Element elem = new Element( "index" );
elem.setAttribute( "name", name );
elem.setAttribute( "internal", String.valueOf( !name.startsWith( "data/" ) ) );
for ( String value : values )
{
Element valueElem = new Element( "value" );
valueElem.setAttribute( "length", String.valueOf( value.length() ) );
valueElem.setText( xmlCleaner.cleanXml( value ) );
elem.addContent( valueElem );
}
return elem;
}
private Map<String, List<String>> getIndexValues( ContentKey key )
{
final HashMap<String, List<String>> map = new HashMap<String, List<String>>();
final Collection<ContentIndexedFields> entities = contentIndexService.getContentIndexedFields( key );
for ( ContentIndexedFields entity : entities )
{
String name = translatePath( entity.getPath() );
List<String> values = map.get( name );
if ( values == null )
{
values = new ArrayList<String>();
map.put( name, values );
}
values.add( translateValue( name, entity.getValue() ) );
}
return map;
}
private String translatePath( String path )
{
return path.replace( '#', '/' );
}
private String translateValue( String name, String value )
{
if ( value.equals( BLANK_REPLACER ) )
{
return "";
}
else if ( M_PUBLISH_TO.equals( name ) && value.equals( BLANK_PUBLISH_TO_REPLACER ) )
{
return "";
}
else if ( M_PUBLISH_FROM.equals( name ) && value.equals( BLANK_PUBLISH_FROM_REPLACER ) )
{
return "";
}
else
{
return value;
}
}
private String serializeDocument( Document doc )
{
// \r is converted to
by default escapeElementEntities XMLOutputter implementation
final XMLOutputter out = new XMLOutputter( Format.getPrettyFormat().setOmitDeclaration( true ) )
{
@Override
public String escapeElementEntities( final String text )
{
return super.escapeElementEntities( text.replaceAll( "\r", "" ) );
}
};
return out.outputString( doc );
}
}