/*
* (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Gagnavarslan ehf
*/
package org.nuxeo.ecm.webdav.backend;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.common.utils.Path;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.PathRef;
public abstract class AbstractVirtualBackend extends AbstractCoreBackend implements VirtualBackend {
private static final Log log = LogFactory.getLog(AbstractVirtualBackend.class);
protected Map<String, Backend> backendMap;
protected LinkedList<String> orderedBackendNames;
protected String rootUrl;
private String backendDisplayName;
private RealBackendFactory realBackendFactory;
protected AbstractVirtualBackend(String name, String rootUrl, CoreSession session,
RealBackendFactory realBackendFactory) {
super(session);
this.backendDisplayName = name;
this.rootUrl = new Path(rootUrl).append(this.backendDisplayName).toString();
this.realBackendFactory = realBackendFactory;
}
protected void registerSimpleBackends(List<DocumentModel> docs) {
List<String> paths = new ArrayList<String>();
for (DocumentModel doc : docs) {
paths.add(doc.getPathAsString());
}
List<String> heads = new ArrayList<String>();
for (int idx = 0; idx < paths.size(); idx++) {
String path = paths.get(idx);
if (isHead(path, paths, idx)) {
heads.add(path);
}
}
for (String head : heads) {
String headName = new Path(head).lastSegment();
String name = headName;
int idx = 1;
while (backendMap.containsKey(name)) {
name = headName + "-" + idx;
idx = idx + 1;
}
Backend backend = realBackendFactory.createBackend(name, head,
new Path(this.rootUrl).append(name).toString(), getSession());
registerBackend(backend);
}
}
private boolean isHead(String path, List<String> paths, int idx) {
int level = new Path(path).segmentCount();
for (int i = idx; i >= 0; i--) {
String other = paths.get(i);
if (path.contains(other)) {
if (new Path(other).segmentCount() == level - 1) {
return false;
}
}
}
return true;
}
@Override
public String getRootPath() {
return "";
}
@Override
public String getRootUrl() {
return rootUrl;
}
@Override
public final boolean isVirtual() {
return true;
}
@Override
public boolean isRoot() {
return false;
}
@Override
public String getBackendDisplayName() {
return backendDisplayName;
}
@Override
public LinkedList<String> getVirtualFolderNames() {
initIfNeed();
if (orderedBackendNames == null) {
return new LinkedList<String>();
}
return orderedBackendNames;
}
protected void registerBackend(Backend backend) {
if (backendMap == null) {
backendMap = new ConcurrentHashMap<String, Backend>();
}
if (orderedBackendNames == null) {
orderedBackendNames = new LinkedList<String>();
}
backendMap.put(backend.getBackendDisplayName(), backend);
orderedBackendNames.add(backend.getBackendDisplayName());
}
@Override
public Backend getBackend(String uri) {
Path path = new Path(uri);
if (path.segmentCount() == 0) {
return this;
} else {
String key = path.segment(0);
initIfNeed();
if (backendMap == null) {
return null;
}
Backend backend = backendMap.get(key);
if (backend == null) {
return null;
}
String location = path.removeFirstSegments(1).toString();
return backend.getBackend(location);
}
}
protected void initIfNeed() {
if (backendMap == null || orderedBackendNames == null) {
backendMap = new HashMap<String, Backend>();
orderedBackendNames = new LinkedList<String>();
init();
}
}
protected abstract void init();
@Override
public boolean isLocked(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public boolean canUnlock(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public String lock(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public boolean unlock(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public String getCheckoutUser(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel resolveLocation(String location) {
throw new UnsupportedOperationException(location);
}
@Override
public Path parseLocation(String location) {
throw new UnsupportedOperationException();
}
@Override
public void removeItem(String location) {
throw new UnsupportedOperationException();
}
@Override
public void removeItem(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public void renameItem(DocumentModel source, String destinationName) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel moveItem(DocumentModel source, PathRef targetParentRef) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel copyItem(DocumentModel source, PathRef targetParentRef) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel createFolder(String parentPath, String name) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel createFile(String parentPath, String name, Blob content) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel createFile(String parentPath, String name) {
throw new UnsupportedOperationException();
}
@Override
public List<DocumentModel> getChildren(DocumentRef ref) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRename(String source, String destination) {
throw new UnsupportedOperationException();
}
@Override
public boolean exists(String location) {
throw new UnsupportedOperationException(location);
}
@Override
public String getDisplayName(DocumentModel doc) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasPermission(DocumentRef docRef, String permission) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel getDocument(String location) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel updateDocument(DocumentModel doc, String name, Blob content) {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel moveItem(DocumentModel source, DocumentRef targetParentRef, String name)
{
throw new UnsupportedOperationException();
}
@Override
public String getVirtualPath(String path) {
initIfNeed();
for (String backendName : orderedBackendNames) {
Backend backend = backendMap.get(backendName);
String url = backend.getVirtualPath(path);
if (StringUtils.isNotEmpty(url)) {
return url;
}
}
return null;
}
@Override
public LinkedList<String> getOrderedBackendNames() {
initIfNeed();
return orderedBackendNames;
}
}