]> git.argeo.org Git - lgpl/argeo-commons.git/blob - AbstractUrlProxy.java
8a66f3102dccebf1a1adb76e3c9accede7673f32
[lgpl/argeo-commons.git] / 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.io.IOUtils;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.argeo.ArgeoException;
34 import org.argeo.jcr.JcrUtils;
35
36 /** Base class for URL based proxys. */
37 public abstract class AbstractUrlProxy implements ResourceProxy {
38 private final static Log log = LogFactory.getLog(AbstractUrlProxy.class);
39
40 private Repository jcrRepository;
41 private Session jcrAdminSession;
42 private String proxyWorkspace = "proxy";
43
44 protected abstract Node retrieve(Session session, String path);
45
46 void init() {
47 try {
48 jcrAdminSession = JcrUtils.loginOrCreateWorkspace(jcrRepository,
49 proxyWorkspace);
50 beforeInitSessionSave(jcrAdminSession);
51 if (jcrAdminSession.hasPendingChanges())
52 jcrAdminSession.save();
53 } catch (Exception e) {
54 JcrUtils.discardQuietly(jcrAdminSession);
55 throw new ArgeoException("Cannot initialize Maven proxy", e);
56 }
57 }
58
59 /**
60 * Called before the (admin) session is saved at the end of the
61 * initialization. Does nothing by default, to be overridden.
62 */
63 protected void beforeInitSessionSave(Session session)
64 throws RepositoryException {
65 }
66
67 void destroy() {
68 JcrUtils.logoutQuietly(jcrAdminSession);
69 }
70
71 /**
72 * Called before the (admin) session is logged out when resources are
73 * released. Does nothing by default, to be overridden.
74 */
75 protected void beforeDestroySessionLogout() throws RepositoryException {
76 }
77
78 public Node proxy(String path) {
79 // we open a JCR session with client credentials in order not to use the
80 // admin session in multiple thread or make it a bottleneck.
81 Node nodeAdmin = null;
82 Node nodeClient = null;
83 Session clientSession = null;
84 try {
85 clientSession = jcrRepository.login(proxyWorkspace);
86 if (!clientSession.itemExists(path)
87 || shouldUpdate(clientSession, path)) {
88 nodeAdmin = retrieveAndSave(path);
89 if (nodeAdmin != null)
90 nodeClient = clientSession.getNode(path);
91 } else
92 nodeClient = clientSession.getNode(path);
93 return nodeClient;
94 } catch (RepositoryException e) {
95 throw new ArgeoException("Cannot proxy " + path, e);
96 } finally {
97 if (nodeClient == null)
98 JcrUtils.logoutQuietly(clientSession);
99 }
100 }
101
102 protected synchronized Node retrieveAndSave(String path) {
103 try {
104 Node node = retrieve(jcrAdminSession, path);
105 if (node == null)
106 return null;
107 jcrAdminSession.save();
108 return node;
109 } catch (RepositoryException e) {
110 JcrUtils.discardQuietly(jcrAdminSession);
111 throw new ArgeoException("Cannot retrieve and save " + path, e);
112 } finally {
113 notifyAll();
114 }
115 }
116
117 /** Session is not saved */
118 protected synchronized Node proxyUrl(Session session, String remoteUrl,
119 String path) throws RepositoryException {
120 Node node = null;
121 if (session.itemExists(path)) {
122 // throw new ArgeoException("Node " + path + " already exists");
123 }
124 InputStream in = null;
125 try {
126 URL u = new URL(remoteUrl);
127 in = u.openStream();
128 node = importFile(session, path, in);
129 } catch (IOException e) {
130 if (log.isDebugEnabled()) {
131 log.debug("Cannot read " + remoteUrl + ", skipping... "
132 + e.getMessage());
133 // log.trace("Cannot read because of ", e);
134 }
135 JcrUtils.discardQuietly(session);
136 } finally {
137 IOUtils.closeQuietly(in);
138 }
139 return node;
140 }
141
142 protected synchronized Node importFile(Session session, String path,
143 InputStream in) throws RepositoryException {
144 Binary binary = null;
145 try {
146 Node content = null;
147 Node node = null;
148 if (!session.itemExists(path)) {
149 node = JcrUtils.mkdirs(session, path, NodeType.NT_FILE,
150 NodeType.NT_FOLDER, false);
151 content = node.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
152 } else {
153 node = session.getNode(path);
154 content = node.getNode(Node.JCR_CONTENT);
155 }
156 binary = session.getValueFactory().createBinary(in);
157 content.setProperty(Property.JCR_DATA, binary);
158 JcrUtils.updateLastModifiedAndParents(node, null);
159 return node;
160 } finally {
161 JcrUtils.closeQuietly(binary);
162 }
163 }
164
165 /** Whether the file should be updated. */
166 protected Boolean shouldUpdate(Session clientSession, String nodePath) {
167 return false;
168 }
169
170 public void setJcrRepository(Repository jcrRepository) {
171 this.jcrRepository = jcrRepository;
172 }
173
174 public void setProxyWorkspace(String localWorkspace) {
175 this.proxyWorkspace = localWorkspace;
176 }
177
178 }