X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.cms.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2Fproxy%2FAbstractUrlProxy.java;fp=org.argeo.cms.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2Fproxy%2FAbstractUrlProxy.java;h=0177636f8da910c6e94eebfc611e6e739c1e0427;hb=bce03099b0d2f1758e7a3d74fba339d0200924d5;hp=0000000000000000000000000000000000000000;hpb=0ea2992e5f3803cd98b5981f27274faa922bc199;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java b/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java new file mode 100644 index 0000000..0177636 --- /dev/null +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java @@ -0,0 +1,153 @@ +package org.argeo.jcr.proxy; + +import java.io.IOException; +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.argeo.api.cms.CmsLog; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; + +/** Base class for URL based proxys. */ +public abstract class AbstractUrlProxy implements ResourceProxy { + private final static CmsLog log = CmsLog.getLog(AbstractUrlProxy.class); + + private Repository jcrRepository; + private Session jcrAdminSession; + private String proxyWorkspace = "proxy"; + + protected abstract Node retrieve(Session session, String path); + + void init() { + try { + jcrAdminSession = JcrUtils.loginOrCreateWorkspace(jcrRepository, proxyWorkspace); + beforeInitSessionSave(jcrAdminSession); + if (jcrAdminSession.hasPendingChanges()) + jcrAdminSession.save(); + } catch (RepositoryException e) { + JcrUtils.discardQuietly(jcrAdminSession); + throw new JcrException("Cannot initialize URL 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(Session session) 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(String path) { + // we open a JCR session with client credentials in order not to use the + // admin session in multiple thread or make it a bottleneck. + Node nodeAdmin = null; + Node nodeClient = null; + Session clientSession = null; + try { + clientSession = jcrRepository.login(proxyWorkspace); + if (!clientSession.itemExists(path) || shouldUpdate(clientSession, path)) { + nodeAdmin = retrieveAndSave(path); + if (nodeAdmin != null) + nodeClient = clientSession.getNode(path); + } else + nodeClient = clientSession.getNode(path); + return nodeClient; + } catch (RepositoryException e) { + throw new JcrException("Cannot proxy " + path, e); + } finally { + if (nodeClient == null) + JcrUtils.logoutQuietly(clientSession); + } + } + + protected synchronized Node retrieveAndSave(String path) { + try { + Node node = retrieve(jcrAdminSession, path); + if (node == null) + return null; + jcrAdminSession.save(); + return node; + } catch (RepositoryException e) { + JcrUtils.discardQuietly(jcrAdminSession); + throw new JcrException("Cannot retrieve and save " + path, e); + } finally { + notifyAll(); + } + } + + /** Session is not saved */ + protected synchronized Node proxyUrl(Session session, String remoteUrl, String path) throws RepositoryException { + Node node = null; + if (session.itemExists(path)) { + // throw new ArgeoJcrException("Node " + path + " already exists"); + } + try (InputStream in = new URL(remoteUrl).openStream()) { + // URL u = new URL(remoteUrl); + // in = u.openStream(); + node = importFile(session, path, in); + } catch (IOException e) { + if (log.isDebugEnabled()) { + log.debug("Cannot read " + remoteUrl + ", skipping... " + e.getMessage()); + // log.trace("Cannot read because of ", e); + } + JcrUtils.discardQuietly(session); + // } finally { + // IOUtils.closeQuietly(in); + } + return node; + } + + protected synchronized Node importFile(Session session, String path, InputStream in) throws RepositoryException { + Binary binary = null; + try { + Node content = null; + Node node = null; + if (!session.itemExists(path)) { + node = JcrUtils.mkdirs(session, path, NodeType.NT_FILE, NodeType.NT_FOLDER, false); + content = node.addNode(Node.JCR_CONTENT, NodeType.NT_UNSTRUCTURED); + } else { + node = session.getNode(path); + content = node.getNode(Node.JCR_CONTENT); + } + binary = session.getValueFactory().createBinary(in); + content.setProperty(Property.JCR_DATA, binary); + JcrUtils.updateLastModifiedAndParents(node, null, true); + return node; + } finally { + JcrUtils.closeQuietly(binary); + } + } + + /** Whether the file should be updated. */ + protected Boolean shouldUpdate(Session clientSession, String nodePath) { + return false; + } + + public void setJcrRepository(Repository jcrRepository) { + this.jcrRepository = jcrRepository; + } + + public void setProxyWorkspace(String localWorkspace) { + this.proxyWorkspace = localWorkspace; + } + +}