/*
* Copyright (C) 2005-2012 BetaCONCEPT Limited
*
* This file is part of Astroboa.
*
* Astroboa is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Astroboa is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Astroboa. If not, see <http://www.gnu.org/licenses/>.
*/
package org.betaconceptframework.astroboa.engine.jcr.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.ValueFormatException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.betaconceptframework.astroboa.api.model.CmsRepositoryEntity;
import org.betaconceptframework.astroboa.api.model.ValueType;
import org.betaconceptframework.astroboa.api.model.exception.CmsException;
import org.betaconceptframework.astroboa.engine.database.dao.CmsRepositoryEntityAssociationDao;
import org.betaconceptframework.astroboa.model.impl.ItemQName;
import org.betaconceptframework.astroboa.model.impl.SaveMode;
/**
*
* @author Gregory Chomatas (gchomatas@betaconcept.com)
* @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
*
*/
public class EntityAssociationUpdateHelper<T extends CmsRepositoryEntity> extends EntityAssociationHelperBase<T> {
public EntityAssociationUpdateHelper(
Session session,
CmsRepositoryEntityAssociationDao cmsRepositoryEntityAssociationDao,
Context context) {
super(session, cmsRepositoryEntityAssociationDao, context);
}
private Node referrerCmsRepositoryEntityNode;
private Node referrerPropertyContainerNode;
private ItemQName referrerPropertyName;
private boolean isReferrerPropertyNameMultivalue;
private Node referrerNodeWhichContainsProperty;
//New Ids to be added
private List<T> valuesToBeAdded;
//Existing values
private List<String> existingValues = new ArrayList<String>();
public void setValuesToBeAdded(List<T> valuesToBeAdded) {
this.valuesToBeAdded = valuesToBeAdded;
}
public void update() throws RepositoryException{
//Initiliaze ids and other variables which will be used through this update
initialise();
loadExistingValues();
//Values to be added will replace existing values
//Before that we must isolate all values that
//must be removed from associations
//and all values that should be added to associations
Map<String,T> newValuesMapToBeAdded = new LinkedHashMap<String, T>();
List<String> listOfNewIdsToBeAdded = new ArrayList<String>();
if (CollectionUtils.isNotEmpty(valuesToBeAdded)){
for (T valueToAdd : valuesToBeAdded){
String idToBeAdded = valueToAdd.getId();
if (StringUtils.isBlank(idToBeAdded))
throw new CmsException("Cms Repository Entity does not have an id" );
newValuesMapToBeAdded.put(idToBeAdded, valueToAdd);
listOfNewIdsToBeAdded.add(idToBeAdded);
}
}
ValueFactory valueFactory = session.getValueFactory();
//Replace values in JCR Node
if (isReferrerPropertyNameMultivalue){
JcrNodeUtils.addMultiValueProperty(referrerNodeWhichContainsProperty,
referrerPropertyName, SaveMode.UPDATE, listOfNewIdsToBeAdded, ValueType.String, valueFactory);
}
else{
if (newValuesMapToBeAdded != null && newValuesMapToBeAdded.size() >1){
throw new CmsException("Must update single value property "+referrerPropertyName.getJcrName()+ " in node "+
referrerNodeWhichContainsProperty.getPath()+ " but found more than one values "+
newValuesMapToBeAdded.toString());
}
JcrNodeUtils.addSimpleProperty(SaveMode.UPDATE,
referrerNodeWhichContainsProperty, referrerPropertyName,
CollectionUtils.isEmpty(listOfNewIdsToBeAdded)? null : listOfNewIdsToBeAdded.get(0), //Expecting at most one value
valueFactory, ValueType.String);
}
}
private void initialise() throws RepositoryException {
referrerNodeWhichContainsProperty = ((referrerPropertyContainerNode == null)? referrerCmsRepositoryEntityNode : referrerPropertyContainerNode);
}
private void loadExistingValues() throws ValueFormatException,
RepositoryException, PathNotFoundException {
if (existingValues != null){
existingValues.clear();
}
else{
existingValues = new ArrayList<String>();
}
List<Value> existingValues = new ArrayList<Value>();
if (referrerNodeWhichContainsProperty.hasProperty(referrerPropertyName.getJcrName())){
if (isReferrerPropertyNameMultivalue){
existingValues = Arrays.asList(referrerNodeWhichContainsProperty.getProperty(referrerPropertyName.getJcrName()).getValues());
}
else{
Value existingValue = referrerNodeWhichContainsProperty.getProperty(referrerPropertyName.getJcrName()).getValue();
existingValues.add(existingValue);
}
if (CollectionUtils.isNotEmpty(existingValues)){
for (Value existingValue: existingValues)
this.existingValues.add(existingValue.getString());
}
}
}
public void setReferrerCmsRepositoryEntityNode(
Node referrerCmsRepositoryEntityNode) {
this.referrerCmsRepositoryEntityNode = referrerCmsRepositoryEntityNode;
}
public void setReferrerPropertyContainerNode(Node referrerPropertyContainerNode) {
this.referrerPropertyContainerNode = referrerPropertyContainerNode;
}
public void setReferrerPropertyName(ItemQName referrerPropertyName) {
this.referrerPropertyName = referrerPropertyName;
}
public void setReferrerPropertyNameMultivalue(
boolean isReferrerPropertyNameMultivalue) {
this.isReferrerPropertyNameMultivalue = isReferrerPropertyNameMultivalue;
}
}