/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florent Guillaume
* Laurent Doguin
*/
package org.eclipse.ecr.core.versioning;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.ecr.core.api.ClientException;
import org.eclipse.ecr.core.api.DocumentException;
import org.eclipse.ecr.core.api.DocumentModel;
import org.eclipse.ecr.core.api.VersioningOption;
import org.eclipse.ecr.core.model.Document;
import org.eclipse.ecr.runtime.model.ComponentContext;
import org.eclipse.ecr.runtime.model.ComponentInstance;
import org.eclipse.ecr.runtime.model.DefaultComponent;
/**
* Versioning service component and implementation.
*/
public class VersioningComponent extends DefaultComponent implements
VersioningService {
private static final Log log = LogFactory.getLog(VersioningComponent.class);
public static final String XP = "versioningService";
public static final String VERSIONING_RULE_XP = "versioningRules";
public VersioningService service;
protected LinkedList<Class<? extends VersioningService>> contribs;
protected Map<String, VersioningRuleDescriptor> versioningRules;
protected LinkedList<DefaultVersioningRuleDescriptor> defaultVersioningRuleList;
protected boolean recompute;
@Override
public void activate(ComponentContext context) throws Exception {
contribs = new LinkedList<Class<? extends VersioningService>>();
versioningRules = new HashMap<String, VersioningRuleDescriptor>();
defaultVersioningRuleList = new LinkedList<DefaultVersioningRuleDescriptor>();
recompute = true;
service = null;
}
@Override
public void deactivate(ComponentContext context) throws Exception {
contribs.clear();
versioningRules.clear();
defaultVersioningRuleList.clear();
service = null;
}
@Override
@SuppressWarnings("unchecked")
public void registerContribution(Object contrib, String xp,
ComponentInstance contributor) throws Exception {
if (XP.equals(xp)) {
if (!(contrib instanceof VersioningServiceDescriptor)) {
log.error("Invalid contribution: "
+ contrib.getClass().getName());
return;
}
VersioningServiceDescriptor desc = (VersioningServiceDescriptor) contrib;
Class<?> klass;
try {
klass = Class.forName(desc.className);
} catch (ClassNotFoundException e) {
log.error("Invalid contribution class: " + desc.className);
return;
}
if (!(VersioningService.class.isAssignableFrom(klass))) {
log.error("Invalid contribution class: " + desc.className);
return;
}
contribs.add((Class<VersioningService>) klass);
log.info("Registered versioning service: " + desc.className);
recompute = true;
} else if (VERSIONING_RULE_XP.equals(xp)) {
if (contrib instanceof VersioningRuleDescriptor) {
VersioningRuleDescriptor typeSaveOptDescriptor = (VersioningRuleDescriptor) contrib;
if (typeSaveOptDescriptor.isEnabled()) {
versioningRules.put(typeSaveOptDescriptor.getTypeName(),
typeSaveOptDescriptor);
} else {
versioningRules.remove(typeSaveOptDescriptor.getTypeName());
}
recompute = true;
} else if (contrib instanceof DefaultVersioningRuleDescriptor) {
defaultVersioningRuleList.add((DefaultVersioningRuleDescriptor) contrib);
recompute = true;
}
} else {
log.error("Unknown extension point " + xp);
}
}
@Override
@SuppressWarnings("unchecked")
public void unregisterContribution(Object contrib, String xp,
ComponentInstance contributor) throws Exception {
if (XP.equals(xp)) {
if (!(contrib instanceof VersioningServiceDescriptor)) {
return;
}
VersioningServiceDescriptor desc = (VersioningServiceDescriptor) contrib;
Class<?> klass;
try {
klass = Class.forName(desc.className);
} catch (ClassNotFoundException e) {
return;
}
if (!(klass.isAssignableFrom(VersioningService.class))) {
return;
}
contribs.remove((Class<VersioningService>) klass);
log.info("Unregistered versioning service: " + desc.className);
} else if (VERSIONING_RULE_XP.equals(xp)) {
if (contrib instanceof VersioningRuleDescriptor) {
VersioningRuleDescriptor typeSaveOptDescriptor = (VersioningRuleDescriptor) contrib;
String typeName = typeSaveOptDescriptor.getTypeName();
if (versioningRules.containsKey(typeName)) {
versioningRules.remove(typeName);
}
} else if (contrib instanceof DefaultVersioningRuleDescriptor) {
defaultVersioningRuleList.remove((DefaultVersioningRuleDescriptor) contrib);
}
log.info("Unregistered versioning rule: " + contributor.getName());
}
recompute = true;
}
protected void recompute() {
Class<? extends VersioningService> klass;
if (contribs.size() == 0) {
klass = StandardVersioningService.class;
} else {
klass = contribs.getLast();
}
if (service == null || klass != service.getClass()) {
try {
service = klass.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
} // else keep old service instance
if (service != null && service instanceof ExtendableVersioningService) {
ExtendableVersioningService extendableService = (ExtendableVersioningService) service;
extendableService.setVersioningRules(versioningRules);
if (!defaultVersioningRuleList.isEmpty()) {
extendableService.setDefaultVersioningRule(defaultVersioningRuleList.getLast());
}
}
}
public VersioningService getService() {
if (recompute) {
recompute();
recompute = false;
}
return service;
}
@Override
public String getVersionLabel(DocumentModel doc) {
return getService().getVersionLabel(doc);
}
@Override
public void doPostCreate(Document doc, Map<String, Serializable> options)
throws DocumentException {
getService().doPostCreate(doc, options);
}
@Override
public List<VersioningOption> getSaveOptions(DocumentModel docModel)
throws ClientException {
return getService().getSaveOptions(docModel);
}
@Override
public VersioningOption doPreSave(Document doc, boolean isDirty,
VersioningOption option, String checkinComment,
Map<String, Serializable> options) throws DocumentException {
return getService().doPreSave(doc, isDirty, option, checkinComment, options);
}
@Override
public Document doPostSave(Document doc, VersioningOption option,
String checkinComment, Map<String, Serializable> options)
throws DocumentException {
return getService().doPostSave(doc, option, checkinComment, options);
}
@Override
public Document doCheckIn(Document doc, VersioningOption option,
String checkinComment) throws DocumentException {
return getService().doCheckIn(doc, option, checkinComment);
}
@Override
public void doCheckOut(Document doc) throws DocumentException {
getService().doCheckOut(doc);
}
}