/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.content.imports;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.enonic.cms.core.content.ContentKey;
import com.enonic.cms.core.content.category.CategoryEntity;
import com.enonic.cms.core.content.contenttype.ContentTypeConfig;
import com.enonic.cms.core.content.contenttype.ContentTypeEntity;
import com.enonic.cms.core.content.contenttype.CtyImportConfig;
import com.enonic.cms.core.content.contenttype.dataentryconfig.DataEntryConfig;
import com.enonic.cms.core.content.index.ContentIndexQuery;
import com.enonic.cms.core.content.index.config.IndexDefinition;
import com.enonic.cms.core.content.index.config.IndexDefinitionBuilder;
import com.enonic.cms.core.content.resultset.ContentResultSet;
import com.enonic.cms.core.search.query.ContentIndexService;
import com.enonic.cms.core.search.query.IndexValueQuery;
import com.enonic.cms.core.search.query.IndexValueResult;
import com.enonic.cms.core.search.query.IndexValueResultSet;
public class ExistingContentBySyncValueResolver
{
private ContentIndexService contentIndexService;
public ExistingContentBySyncValueResolver( final ContentIndexService contentIndexService )
{
this.contentIndexService = contentIndexService;
}
public Map<String, ContentKey> resolve( final CategoryEntity category, final CtyImportConfig importConfig )
{
if ( importConfig.isSyncMappedToContentKey() )
{
return resolveContentKeysBySyncValueFromAllContentInCategory( category );
}
else
{
return resolveContentKeysBySyncValueFromIndexedField( category, importConfig );
}
}
private Map<String, ContentKey> resolveContentKeysBySyncValueFromAllContentInCategory( final CategoryEntity category )
{
ContentIndexQuery contentQuery = new ContentIndexQuery( "categorykey = " + category.getKey().toString() );
contentQuery.setReturnAllHits( true );
ContentResultSet contentResultSet = contentIndexService.query( contentQuery );
List<ContentKey> contentKeysInCategory = contentResultSet.getKeys();
final Map<String, ContentKey> contentKeysBySyncValue = new HashMap<String, ContentKey>( contentKeysInCategory.size() );
for ( ContentKey contentKey : contentKeysInCategory )
{
contentKeysBySyncValue.put( contentKey.toString(), contentKey );
}
return contentKeysBySyncValue;
}
private Map<String, ContentKey> resolveContentKeysBySyncValueFromIndexedField( final CategoryEntity category,
final CtyImportConfig importConfig )
{
final String syncXpath = getSyncXpath( category, importConfig );
final IndexValueQuery query = new IndexValueQuery( syncXpath );
query.setReturnAllHits( true );
query.setCategoryFilter( Arrays.asList( category.getKey() ) );
final IndexValueResultSet resSet = contentIndexService.query( query );
final Map<String, ContentKey> contentKeysBySyncValue = new HashMap<String, ContentKey>();
for ( int i = 0; i < resSet.getCount(); i++ )
{
final IndexValueResult res = resSet.getIndexValue( i );
final ContentKey contentKey = res.getContentKey();
final String syncValue = res.getValue();
Object previousValue = contentKeysBySyncValue.put( syncValue, contentKey );
if ( previousValue != null )
{
throw new ImportException(
"Could not uniquely identify content in category, category key: " + category.getKey() + ", category path: \"" +
category.getPathAsString() + "\" using xpath: \"" + syncXpath + "\" from sync field: \"" + importConfig.getSync() +
"\". Duplicate sync value: \"" + syncValue + "\"" );
}
}
return contentKeysBySyncValue;
}
private String getSyncXpath( CategoryEntity category, CtyImportConfig importConfig )
{
final ContentTypeConfig config = category.getContentType().getContentTypeConfig();
final DataEntryConfig dataEntryConfig = config.getInputConfig( importConfig.getSync() );
final String syncXpath = dataEntryConfig.getXpath();
if ( !isXpathIndexed( category.getContentType(), syncXpath ) )
{
throw new ImportException(
"Could not find index for sync field: \"" + importConfig.getSync() + "\" with xpath: \"" + syncXpath +
"\" in category, category key: " + category.getKey() + ", category name: \"" + category.getName() +
"\". Sync field must be indexed." );
}
return syncXpath;
}
private boolean isXpathIndexed( ContentTypeEntity contentType, String syncXpath )
{
final List<IndexDefinition> indexes = new IndexDefinitionBuilder().buildList( contentType );
for ( IndexDefinition index : indexes )
{
if ( index.getXPath().equals( syncXpath ) )
{
return true;
}
}
return false;
}
}