/*
* Copyright 2015 Time Warner Cable, Inc.
*
* 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.
*/
package com.twcable.jackalope.impl.cq;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.Revision;
import com.day.cq.wcm.api.Template;
import com.day.cq.wcm.api.WCMException;
import com.day.cq.wcm.api.msm.Blueprint;
import com.google.common.collect.Lists;
import com.twcable.jackalope.JcrConstants;
import com.twcable.jackalope.impl.common.Paths;
import com.twcable.jackalope.impl.jcr.ValueImpl;
import com.twcable.jackalope.impl.sling.NodeResourceImpl;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.util.Calendar;
import java.util.Collection;
/**
* Page Manager implementation.
*/
public class PageManagerImpl implements PageManager {
private final ResourceResolver resolver;
private final Session session;
public PageManagerImpl(ResourceResolver resolver) {
this.resolver = resolver;
Session session = resolver.adaptTo(Session.class);
if (session == null) throw new IllegalArgumentException("Resolver must be adaptable to Session.");
this.session = session;
}
@Override
public Page getPage(String path) {
Resource resource = resolver.getResource(path);
return resource != null ? resource.adaptTo(Page.class) : null;
}
@Override
public Page getContainingPage(Resource resource) {
if (resource == null) return null;
String path = resource.getPath();
while (!Paths.isRoot(path)) {
Page page = getPage(path);
if (page != null) return page;
path = path.substring(0, path.lastIndexOf("/"));
}
return null;
}
@Override
public Page getContainingPage(String path) {
return getContainingPage(resolver.getResource(path));
}
@Override
public Page create(String parentPath, String pageName, String template, String title) throws WCMException {
return create(parentPath, pageName, template, title, true);
}
@Override
public Page create(String parentPath, String pageName, String template, String title,
boolean autoSave) throws WCMException {
if (parentPath == null) throw new IllegalArgumentException("Parent path can't be null.");
if (pageName == null && title == null)
throw new IllegalArgumentException("Page and title name can't be both null.");
if (template != null && !template.isEmpty())
throw new UnsupportedOperationException("Templates are not supported.");
try {
Node parent = JcrUtils.getOrCreateByPath(parentPath, JcrConstants.NT_UNSTRUCTURED, session);
if (pageName == null || pageName.isEmpty())
pageName = JcrUtil.createValidName(title, JcrUtil.HYPHEN_LABEL_CHAR_MAPPING);
if (!JcrUtil.isValidName(pageName)) throw new IllegalArgumentException("Illegal page name: " + pageName);
Node pageNode = parent.addNode(pageName, JcrConstants.CQ_PAGE);
Node contentNode = pageNode.addNode("jcr:content", JcrConstants.CQ_PAGE_CONTENT);
if (title != null && !title.isEmpty()) contentNode.setProperty("jcr:title", title);
if (autoSave) {
session.save();
}
return getPage(pageNode.getPath());
}
catch (RepositoryException e) {
throw new WCMException("Unable to create page", e);
}
}
@Override
public Page move(Page page, String destination, String beforeName, boolean shallow, boolean resolveConflicts,
String[] adjustRefs) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Resource move(Resource resource, String destination, String beforeName, boolean shallow, boolean resolveConflicts, String[] adjustRefs) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Page copy(Page page, String destination, String beforeName, boolean shallow, boolean resolveConflict) throws WCMException {
return copy(page, destination, beforeName, shallow, resolveConflict, false);
}
@Override
public Page copy(Page page, String destination, String beforeName, boolean shallow, boolean resolveConflict, boolean autoSave) throws WCMException {
if (beforeName != null && !beforeName.isEmpty())
throw new UnsupportedOperationException("Ordering not supported.");
if (resolveConflict) throw new UnsupportedOperationException("Conflict resolution not supported.");
if (!shallow) throw new UnsupportedOperationException("Recursive page copy not supported.");
Page newPage = null;
try {
newPage = create(destination, page.getName(), null, page.getTitle());
Resource contentResource = newPage.getContentResource();
if (contentResource == null) throw new WCMException("Content resource is null.");
Node contentNode = contentResource.adaptTo(Node.class);
ValueMap properties = newPage.getProperties();
if (contentNode != null && properties != null)
for (String key : properties.keySet()) contentNode.setProperty(key, new ValueImpl(properties.get(key)));
else throw new WCMException("Unable to copy properties");
for (Resource child : Lists.newArrayList(page.getContentResource().listChildren())) {
copy(child, contentResource.getPath() + "/" + child.getName(), null, false, false, false);
}
if (autoSave) session.save();
return newPage;
}
catch (RepositoryException e) {
delete(newPage, false);
throw new WCMException("Unable to copy properties.", e);
}
catch (WCMException e) {
delete(newPage, false);
throw e;
}
}
@Override
public Resource copy(Resource resource, String destination, String beforeName, boolean shallow, boolean resolveConflict) throws WCMException {
return copy(resource, destination, beforeName, shallow, resolveConflict, false);
}
@Override
public Resource copy(Resource resource, String destination, String beforeName, boolean shallow, boolean resolveConflict, boolean autoSave) throws WCMException {
if (beforeName != null && !beforeName.isEmpty())
throw new UnsupportedOperationException("Ordering not supported.");
if (resolveConflict) throw new UnsupportedOperationException("Conflict resolution not supported.");
try {
int index = destination.lastIndexOf("/");
String parentPath = destination.substring(0, index);
String name = destination.substring(index + 1);
Node parent = JcrUtils.getOrCreateByPath(parentPath, JcrConstants.NT_UNSTRUCTURED, session);
Node node = resource.adaptTo(Node.class);
if (node == null) throw new WCMException("Unable to get source node.");
if (node.hasNode(name)) throw new WCMException("Node already exists at destination.");
Node newNode = parent.addNode(name, node.getPrimaryNodeType().toString());
ValueMap properties = resource.adaptTo(ValueMap.class);
for (String key : properties.keySet()) newNode.setProperty(key, new ValueImpl(properties.get(key)));
if (!shallow && node.hasNodes())
for (Resource child : Lists.newArrayList(resource.listChildren()))
copy(child, resource.getPath() + "/" + child.getName(), null, false, false, false);
if (autoSave) session.save();
return new NodeResourceImpl(resolver, newNode);
}
catch (RepositoryException e) {
try {
if (session.itemExists(destination)) session.removeItem(destination);
}
catch (RepositoryException e1) {
e1.printStackTrace();
}
throw new WCMException("Unable to copy resource.", e);
}
catch (WCMException e) {
try {
if (session.itemExists(destination)) session.removeItem(destination);
}
catch (RepositoryException e1) {
e1.printStackTrace();
}
throw e;
}
}
@Override
public void delete(Page page, boolean shallow) throws WCMException {
delete(page, shallow, true);
}
@Override
public void delete(Page page, boolean shallow, boolean autoSave) throws WCMException {
if (page == null) return;
if (!shallow) delete(page.adaptTo(Resource.class), false, autoSave);
else delete(page.getContentResource(), true, autoSave);
}
@Override
public void delete(Resource resource, boolean shallow) throws WCMException {
delete(resource, shallow, true);
}
@Override
public void delete(Resource resource, boolean shallow, boolean autoSave) throws WCMException {
if (resource == null) return;
Node node = resource.adaptTo(Node.class);
if (node == null) return;
try {
session.removeItem(node.getPath());
if (autoSave) {
session.save();
}
}
catch (RepositoryException e) {
throw new WCMException("Could not delete resource.", e);
}
}
@Override
public void order(Page page, String beforeName) throws WCMException {
order(page, beforeName, true);
}
@Override
public void order(Page page, String beforeName, boolean autoSave) throws WCMException {
if (page == null) return;
order(page.getContentResource(), beforeName, autoSave);
}
@Override
public void order(Resource resource, String beforeName) throws WCMException {
order(resource, beforeName, true);
}
@Override
public void order(Resource resource, String beforeName, boolean autoSave) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Template getTemplate(String s) {
throw new UnsupportedOperationException();
}
@Override
public Collection<Template> getTemplates(String s) {
throw new UnsupportedOperationException();
}
@Override
@SuppressWarnings("deprecation")
public Collection<Blueprint> getBlueprints(String s) {
throw new UnsupportedOperationException();
}
@Override
public Revision createRevision(Page page) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Revision createRevision(Page page, String s, String s1) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Collection<Revision> getRevisions(String s, Calendar calendar) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Collection<Revision> getRevisions(String s, Calendar calendar, boolean b) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Collection<Revision> getChildRevisions(String s, Calendar calendar) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Collection<Revision> getChildRevisions(String s, Calendar calendar, boolean b) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Collection<Revision> getChildRevisions(String s, String s1, Calendar calendar) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Page restore(String s, String s1) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Page restoreTree(String s, Calendar calendar) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public Page restoreTree(String s, Calendar calendar, boolean b) throws WCMException {
throw new UnsupportedOperationException();
}
@Override
public void touch(Node node, boolean b, Calendar calendar, boolean b1) throws WCMException {
throw new UnsupportedOperationException();
}
}