+package org.argeo.jcr.proxy;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+
+/** Base class for URL based proxys. */
+public abstract class AbstractUrlProxy implements ResourceProxy {
+ private final static Log log = LogFactory.getLog(AbstractUrlProxy.class);
+
+ private Repository jcrRepository;
+ private Session jcrAdminSession;
+
+ protected abstract String retrieve(String relativePath);
+
+ void init() {
+ try {
+ jcrAdminSession = jcrRepository.login();
+ beforeInitSessionSave();
+ if (jcrAdminSession.hasPendingChanges())
+ jcrAdminSession.save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(jcrAdminSession);
+ throw new ArgeoException("Cannot initialize Maven proxy", e);
+ }
+ }
+
+ /**
+ * Called before the (admin) session is saved at the end of the
+ * initialization. Does nothing by default, to be overridden.
+ */
+ protected void beforeInitSessionSave() throws RepositoryException {
+ }
+
+ void destroy() {
+ JcrUtils.logoutQuietly(jcrAdminSession);
+ }
+
+ /**
+ * Called before the (admin) session is logged out when resources are
+ * released. Does nothing by default, to be overridden.
+ */
+ protected void beforeDestroySessionLogout() throws RepositoryException {
+ }
+
+ public Node proxy(Session jcrSession, String path) {
+ Node node;
+ try {
+ String nodePath = getNodePath(path);
+ if (!jcrSession.itemExists(nodePath)) {
+ String nodeIdentifier = retrieve(path);
+ if (nodeIdentifier == null) {
+ // log.warn("Could not proxy " + path);
+ return null;
+ } else {
+ node = jcrSession.getNodeByIdentifier(nodeIdentifier);
+ }
+ } else {
+ node = jcrSession.getNode(nodePath);
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot proxy " + path, e);
+ }
+ return node;
+ }
+
+ protected Node proxyUrl(String baseUrl, String path) {
+ Node node = null;
+ String remoteUrl = baseUrl + path;
+ if (log.isTraceEnabled())
+ log.trace("baseUrl=" + remoteUrl);
+ InputStream in = null;
+ try {
+ URL u = new URL(remoteUrl);
+ in = u.openStream();
+ node = importFile(getNodePath(path), in);
+ if (log.isDebugEnabled())
+ log.debug("Imported " + remoteUrl + " to " + node);
+ } catch (Exception e) {
+ if (log.isTraceEnabled())
+ log.trace("Cannot read " + remoteUrl + ", skipping... "
+ + e.getMessage());
+ if (log.isTraceEnabled()) {
+ log.trace("Cannot read because of ", e);
+ }
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+
+ return node;
+ }
+
+ protected synchronized Node importFile(String nodePath, InputStream in) {
+ // FIXME allow parallel proxying
+ Binary binary = null;
+ try {
+ Node node = JcrUtils.mkdirs(jcrAdminSession, nodePath,
+ NodeType.NT_FILE, NodeType.NT_FOLDER, false);
+ Node content = node.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
+ binary = jcrAdminSession.getValueFactory().createBinary(in);
+ content.setProperty(Property.JCR_DATA, binary);
+ jcrAdminSession.save();
+ return node;
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(jcrAdminSession);
+ throw new ArgeoException("Cannot initialize Maven proxy", e);
+ } finally {
+ JcrUtils.closeQuietly(binary);
+ }
+ }
+
+ protected Session getJcrAdminSession() {
+ return jcrAdminSession;
+ }
+
+ public void setJcrRepository(Repository jcrRepository) {
+ this.jcrRepository = jcrRepository;
+ }
+
+}