/*
* Copyright (C) 2012 Tirasa
*
* 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 net.tirasa.hct.cocoon.sax;
import java.io.BufferedInputStream;
import java.net.URL;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import net.tirasa.hct.repository.HCTConnManager;
import net.tirasa.hct.util.ObjectUtils;
import org.apache.cocoon.pipeline.ProcessingException;
import org.apache.cocoon.pipeline.SetupException;
import org.apache.cocoon.pipeline.caching.CacheKey;
import org.apache.cocoon.pipeline.caching.TimestampURLCacheKey;
import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
import org.apache.cocoon.sitemap.component.AbstractReader;
import org.apache.commons.io.IOUtils;
import org.hippoecm.hst.content.beans.standard.HippoAsset;
import org.hippoecm.hst.content.beans.standard.HippoGalleryImageBean;
import org.hippoecm.hst.content.beans.standard.HippoGalleryImageSet;
import org.hippoecm.hst.content.beans.standard.HippoItem;
import org.hippoecm.hst.content.beans.standard.HippoResource;
import org.hippoecm.hst.servlet.utils.ResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HippoRepositoryReader extends AbstractReader implements CachingPipelineComponent {
private enum ImageType {
thumbnail,
original
}
private static final Logger LOG = LoggerFactory.getLogger(HippoRepositoryReader.class);
private transient String uuid;
private transient long lastmodified;
private transient String contentType;
public HippoRepositoryReader() {
super();
}
public HippoRepositoryReader(final URL source) {
super(source);
}
@Override
@SuppressWarnings("unchecked")
public void setConfiguration(final Map<String, ? extends Object> configuration) {
this.setup((Map<String, Object>) configuration);
}
@Override
public void setup(final Map<String, Object> parameters) {
if (parameters == null) {
return;
}
if (parameters.containsKey("source")) {
super.setSource((URL) parameters.get("source"));
}
if (this.source == null) {
throw new SetupException(getClass().getSimpleName() + " has no source configured to read from.");
}
// Take original URL from the file:/ for to an absolute path in the Hippo repository
String nodePath = this.source.toExternalForm().substring(source.toExternalForm().indexOf(':') + 1);
// Try to guess if this is an image (and adapt path on repository accordingly)
final ImageType imageType = nodePath.endsWith(":" + ImageType.thumbnail.name())
? ImageType.thumbnail : ImageType.original;
if (nodePath.endsWith(":" + imageType.name())) {
LOG.debug("Selected image type is {}", imageType);
nodePath = nodePath.substring(0, nodePath.lastIndexOf(':'));
}
final HCTConnManager connManager = HCTConnManager.getBinaryInstance();
try {
final HippoItem obj = ObjectUtils.getHippoItem(connManager, nodePath);
if (obj instanceof HippoGalleryImageSet) {
final HippoGalleryImageBean imgBean = imageType == ImageType.thumbnail
? ((HippoGalleryImageSet) obj).getThumbnail() : ((HippoGalleryImageSet) obj).getOriginal();
this.lastmodified = imgBean.getLastModified().getTimeInMillis();
this.uuid = imgBean.getNode().getIdentifier();
} else if (obj instanceof HippoAsset) {
final List<HippoResource> resources = ((HippoAsset) obj).getChildBeans(HippoResource.class);
if (resources != null && !resources.isEmpty()) {
final HippoResource asset = resources.get(0);
this.lastmodified = asset.getLastModified().getTimeInMillis();
this.uuid = asset.getNode().getIdentifier();
}
} else {
if (obj == null) {
LOG.warn("Unexpected null node");
} else {
LOG.warn("Unexpected node type: {}", obj.getClass().getName());
}
this.lastmodified = -1;
this.uuid = null;
}
} catch (Exception e) {
throw new ProcessingException("While reading " + nodePath, e);
} finally {
connManager.logout();
}
}
@Override
public String getContentType() {
return contentType;
}
@Override
public CacheKey constructCacheKey() {
if (this.source == null) {
throw new SetupException(getClass().getSimpleName() + " has no source configured to read from.");
}
return new TimestampURLCacheKey(this.source, this.lastmodified);
}
@Override
public void execute() {
if (this.uuid == null) {
throw new IllegalArgumentException(getClass().getSimpleName() + " wasn't able to read from given URL.");
}
final HCTConnManager connManager = HCTConnManager.getBinaryInstance();
BufferedInputStream repositoryIS = null;
try {
final Node node = connManager.getSession().getNodeByIdentifier(this.uuid);
this.contentType = node.getProperty(ResourceUtils.DEFAULT_BINARY_MIME_TYPE_PROP_NAME).getString();
repositoryIS = new BufferedInputStream(node.getProperty(
ResourceUtils.DEFAULT_BINARY_DATA_PROP_NAME).getBinary().getStream());
final byte[] buffer = new byte[1024];
while (repositoryIS.available() != 0) {
final int len = repositoryIS.read(buffer);
this.outputStream.write(buffer, 0, len);
}
} catch (Exception e) {
throw new ProcessingException("While reading node", e);
} finally {
IOUtils.closeQuietly(repositoryIS);
connManager.logout();
}
}
}