RelationsServiceImpl.java
/*
* Copyright (C) 2003-2007 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.services.cms.relations.impl;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Session;
import javax.jcr.Value;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.cms.relations.RelationsService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.picocontainer.Startable;
/**
* @author monica franceschini
*/
public class RelationsServiceImpl implements RelationsService, Startable {
private static final String RELATION_MIXIN = "exo:relationable";
private static final String RELATION_PROP = "exo:relation";
private RepositoryService repositoryService_;
private static final Log LOG = ExoLogger.getLogger(RelationsServiceImpl.class.getName());
public RelationsServiceImpl(RepositoryService repositoryService,
NodeHierarchyCreator nodeHierarchyCreator, InitParams params) {
repositoryService_ = repositoryService;
}
/**
* {@inheritDoc}
*/
public boolean hasRelations(Node node) throws Exception {
if (node.isNodeType(RELATION_MIXIN)) return true;
return false;
}
/**
* Get node by UUID
* @param uuid The specified UUI.
* @param repository The name of repository
* @param provider SessionProvider
* @see SessionProvider
* @return Node with specified UUID
* @throws Exception
*/
private Node getNodeByUUID(String uuid, SessionProvider provider) throws Exception {
ManageableRepository manageRepo = repositoryService_.getCurrentRepository();
String[] workspaces = manageRepo.getWorkspaceNames() ;
for(String ws : workspaces) {
try{
return provider.getSession(ws,manageRepo).getNodeByUUID(uuid) ;
} catch(Exception e) {
continue ;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public List<Node> getRelations(Node node, SessionProvider provider) {
List<Node> rels = new ArrayList<Node>();
try {
if(node.hasProperty(RELATION_PROP)) {
Value[] values = node.getProperty(RELATION_PROP).getValues();
for (int i = 0; i < values.length; i++) {
if(getNodeByUUID(values[i].getString(), provider) != null) {
rels.add(getNodeByUUID(values[i].getString(), provider));
}
}
}
} catch(Exception e) {
if (LOG.isWarnEnabled()) {
LOG.warn(e.getMessage());
}
}
return rels ;
}
/**
* {@inheritDoc}
*/
public void removeRelation(Node node, String relationPath) throws Exception {
List<Value> vals = new ArrayList<Value>();
if (!"*".equals(relationPath) && node.hasProperty(RELATION_PROP)) {
SessionProvider provider = SessionProvider.createSystemProvider() ;
Property relations = node.getProperty(RELATION_PROP);
if (relations != null) {
Value[] values = relations.getValues();
String uuid2Remove = null;
for (int i = 0; i < values.length; i++) {
String uuid = values[i].getString();
Node refNode = getNodeByUUID(uuid, provider);
if(refNode == null) continue ;
if (refNode.getPath().equals(relationPath)) uuid2Remove = uuid;
else vals.add(values[i]);
}
if (uuid2Remove == null) return;
}
provider.close();
if(vals.size() == 0) node.removeMixin(RELATION_MIXIN);
else node.setProperty(RELATION_PROP, vals.toArray(new Value[vals.size()]));
node.save() ;
}
}
/**
* {@inheritDoc}
*/
public void addRelation(Node node, String relationPath,String workspace) throws Exception {
SessionProvider provider = SessionProvider.createSystemProvider() ;
Session session = getSession(workspace,provider) ;
Node catNode = (Node) session.getItem(relationPath);
if(!catNode.isNodeType("mix:referenceable")) {
catNode.addMixin("mix:referenceable") ;
catNode.save() ;
session.save() ;
}
Value value2add = session.getValueFactory().createValue(catNode);
if (!node.isNodeType(RELATION_MIXIN)) {
node.addMixin(RELATION_MIXIN);
node.setProperty(RELATION_PROP, new Value[] {value2add});
node.save() ;
session.save() ;
} else {
List<Value> vals = new ArrayList<Value>();
Value[] values = node.getProperty(RELATION_PROP).getValues();
for (int i = 0; i < values.length; i++) {
Value value = values[i];
String uuid = value.getString();
Node refNode = null ;
try {
refNode = getNodeByUUID(uuid, provider) ;
} catch(ItemNotFoundException ie) {
removeRelation(node, relationPath) ;
continue ;
}
if(refNode.getPath().equals(relationPath)) return;
vals.add(value);
}
vals.add(value2add);
node.setProperty(RELATION_PROP, vals.toArray(new Value[vals.size()]));
node.save() ;
session.save() ;
session.logout();
provider.close();
}
}
/**
* {@inheritDoc}
*/
public void start() {
}
/**
* {@inheritDoc}
*/
public void stop() {
}
/**
* {@inheritDoc}
*/
public void init() throws Exception {
}
/**
* Get session of respository
* @see Session
* @return Session
* @throws Exception
*/
protected Session getSession() throws Exception {
ManageableRepository manageableRepository = repositoryService_.getCurrentRepository();
String workspaceName = manageableRepository.getConfiguration().getSystemWorkspaceName();
return manageableRepository.getSystemSession(workspaceName);
}
/**
* Get session of workspace
* @param workspace The name of workspace
* @param provider SessionProvider
* @see SessionProvider
* @return Session
* @throws Exception
*/
private Session getSession(String workspace, SessionProvider provider) throws Exception {
ManageableRepository manageableRepository = repositoryService_.getCurrentRepository();
return provider.getSession(workspace, manageableRepository);
}
}