]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java
Move file system support to JCR bundle.
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / proxy / AbstractUrlProxy.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.jcr.proxy;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.net.URL;
21
22 import javax.jcr.Binary;
23 import javax.jcr.Node;
24 import javax.jcr.Property;
25 import javax.jcr.Repository;
26 import javax.jcr.RepositoryException;
27 import javax.jcr.Session;
28 import javax.jcr.nodetype.NodeType;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.argeo.jcr.ArgeoJcrException;
33 import org.argeo.jcr.JcrUtils;
34
35 /** Base class for URL based proxys. */
36 public abstract class AbstractUrlProxy implements ResourceProxy {
37 private final static Log log = LogFactory.getLog(AbstractUrlProxy.class);
38
39 private Repository jcrRepository;
40 private Session jcrAdminSession;
41 private String proxyWorkspace = "proxy";
42
43 protected abstract Node retrieve(Session session, String path);
44
45 void init() {
46 try {
47 jcrAdminSession = JcrUtils.loginOrCreateWorkspace(jcrRepository, proxyWorkspace);
48 beforeInitSessionSave(jcrAdminSession);
49 if (jcrAdminSession.hasPendingChanges())
50 jcrAdminSession.save();
51 } catch (Exception e) {
52 JcrUtils.discardQuietly(jcrAdminSession);
53 throw new ArgeoJcrException("Cannot initialize Maven proxy", e);
54 }
55 }
56
57 /**
58 * Called before the (admin) session is saved at the end of the initialization.
59 * Does nothing by default, to be overridden.
60 */
61 protected void beforeInitSessionSave(Session session) throws RepositoryException {
62 }
63
64 void destroy() {
65 JcrUtils.logoutQuietly(jcrAdminSession);
66 }
67
68 /**
69 * Called before the (admin) session is logged out when resources are released.
70 * Does nothing by default, to be overridden.
71 */
72 protected void beforeDestroySessionLogout() throws RepositoryException {
73 }
74
75 public Node proxy(String path) {
76 // we open a JCR session with client credentials in order not to use the
77 // admin session in multiple thread or make it a bottleneck.
78 Node nodeAdmin = null;
79 Node nodeClient = null;
80 Session clientSession = null;
81 try {
82 clientSession = jcrRepository.login(proxyWorkspace);
83 if (!clientSession.itemExists(path) || shouldUpdate(clientSession, path)) {
84 nodeAdmin = retrieveAndSave(path);
85 if (nodeAdmin != null)
86 nodeClient = clientSession.getNode(path);
87 } else
88 nodeClient = clientSession.getNode(path);
89 return nodeClient;
90 } catch (RepositoryException e) {
91 throw new ArgeoJcrException("Cannot proxy " + path, e);
92 } finally {
93 if (nodeClient == null)
94 JcrUtils.logoutQuietly(clientSession);
95 }
96 }
97
98 protected synchronized Node retrieveAndSave(String path) {
99 try {
100 Node node = retrieve(jcrAdminSession, path);
101 if (node == null)
102 return null;
103 jcrAdminSession.save();
104 return node;
105 } catch (RepositoryException e) {
106 JcrUtils.discardQuietly(jcrAdminSession);
107 throw new ArgeoJcrException("Cannot retrieve and save " + path, e);
108 } finally {
109 notifyAll();
110 }
111 }
112
113 /** Session is not saved */
114 protected synchronized Node proxyUrl(Session session, String remoteUrl, String path) throws RepositoryException {
115 Node node = null;
116 if (session.itemExists(path)) {
117 // throw new ArgeoJcrException("Node " + path + " already exists");
118 }
119 try (InputStream in = new URL(remoteUrl).openStream()) {
120 // URL u = new URL(remoteUrl);
121 // in = u.openStream();
122 node = importFile(session, path, in);
123 } catch (IOException e) {
124 if (log.isDebugEnabled()) {
125 log.debug("Cannot read " + remoteUrl + ", skipping... " + e.getMessage());
126 // log.trace("Cannot read because of ", e);
127 }
128 JcrUtils.discardQuietly(session);
129 // } finally {
130 // IOUtils.closeQuietly(in);
131 }
132 return node;
133 }
134
135 protected synchronized Node importFile(Session session, String path, InputStream in) throws RepositoryException {
136 Binary binary = null;
137 try {
138 Node content = null;
139 Node node = null;
140 if (!session.itemExists(path)) {
141 node = JcrUtils.mkdirs(session, path, NodeType.NT_FILE, NodeType.NT_FOLDER, false);
142 content = node.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
143 } else {
144 node = session.getNode(path);
145 content = node.getNode(Node.JCR_CONTENT);
146 }
147 binary = session.getValueFactory().createBinary(in);
148 content.setProperty(Property.JCR_DATA, binary);
149 JcrUtils.updateLastModifiedAndParents(node, null);
150 return node;
151 } finally {
152 JcrUtils.closeQuietly(binary);
153 }
154 }
155
156 /** Whether the file should be updated. */
157 protected Boolean shouldUpdate(Session clientSession, String nodePath) {
158 return false;
159 }
160
161 public void setJcrRepository(Repository jcrRepository) {
162 this.jcrRepository = jcrRepository;
163 }
164
165 public void setProxyWorkspace(String localWorkspace) {
166 this.proxyWorkspace = localWorkspace;
167 }
168
169 }