View Javadoc
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;
17  
18  import java.io.InputStream;
19  import java.math.BigDecimal;
20  import java.util.Arrays;
21  import java.util.Calendar;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import javax.jcr.Binary;
27  import javax.jcr.Credentials;
28  import javax.jcr.LoginException;
29  import javax.jcr.NoSuchWorkspaceException;
30  import javax.jcr.PropertyType;
31  import javax.jcr.Repository;
32  import javax.jcr.RepositoryException;
33  import javax.jcr.Session;
34  import javax.jcr.Value;
35  import javax.jcr.ValueFormatException;
36  
37  /**
38   * Wrapper around a JCR repository which allows to simplify configuration and
39   * intercept some actions. It exposes itself as a {@link Repository}.
40   */
41  public abstract class JcrRepositoryWrapper implements Repository {
42  	// private final static Log log = LogFactory
43  	// .getLog(JcrRepositoryWrapper.class);
44  
45  	// wrapped repository
46  	private Repository repository;
47  
48  	private Map<String, String> additionalDescriptors = new HashMap<>();
49  
50  	private Boolean autocreateWorkspaces = false;
51  
52  	public JcrRepositoryWrapper(Repository repository) {
53  		setRepository(repository);
54  	}
55  
56  	/**
57  	 * Empty constructor
58  	 */
59  	public JcrRepositoryWrapper() {
60  	}
61  
62  	// /** Initializes */
63  	// public void init() {
64  	// }
65  	//
66  	// /** Shutdown the repository */
67  	// public void destroy() throws Exception {
68  	// }
69  
70  	protected void putDescriptor(String key, String value) {
71  		if (Arrays.asList(getRepository().getDescriptorKeys()).contains(key))
72  			throw new IllegalArgumentException("Descriptor key " + key + " is already defined in wrapped repository");
73  		if (value == null)
74  			additionalDescriptors.remove(key);
75  		else
76  			additionalDescriptors.put(key, value);
77  	}
78  
79  	/*
80  	 * DELEGATED JCR REPOSITORY METHODS
81  	 */
82  
83  	public String getDescriptor(String key) {
84  		if (additionalDescriptors.containsKey(key))
85  			return additionalDescriptors.get(key);
86  		return getRepository().getDescriptor(key);
87  	}
88  
89  	public String[] getDescriptorKeys() {
90  		if (additionalDescriptors.size() == 0)
91  			return getRepository().getDescriptorKeys();
92  		List<String> keys = Arrays.asList(getRepository().getDescriptorKeys());
93  		keys.addAll(additionalDescriptors.keySet());
94  		return keys.toArray(new String[keys.size()]);
95  	}
96  
97  	/** Central login method */
98  	public Session login(Credentials credentials, String workspaceName)
99  			throws LoginException, NoSuchWorkspaceException, RepositoryException {
100 		Session session;
101 		try {
102 			session = getRepository(workspaceName).login(credentials, workspaceName);
103 		} catch (NoSuchWorkspaceException e) {
104 			if (autocreateWorkspaces && workspaceName != null)
105 				session = createWorkspaceAndLogsIn(credentials, workspaceName);
106 			else
107 				throw e;
108 		}
109 		processNewSession(session, workspaceName);
110 		return session;
111 	}
112 
113 	public Session login() throws LoginException, RepositoryException {
114 		return login(null, null);
115 	}
116 
117 	public Session login(Credentials credentials) throws LoginException, RepositoryException {
118 		return login(credentials, null);
119 	}
120 
121 	public Session login(String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException {
122 		return login(null, workspaceName);
123 	}
124 
125 	/** Called after a session has been created, does nothing by default. */
126 	protected void processNewSession(Session session, String workspaceName) {
127 	}
128 
129 	/**
130 	 * Wraps access to the repository, making sure it is available.
131 	 * 
132 	 * @deprecated Use {@link #getDefaultRepository()} instead.
133 	 */
134 	@Deprecated
135 	protected synchronized Repository getRepository() {
136 		return getDefaultRepository();
137 	}
138 
139 	protected synchronized Repository getDefaultRepository() {
140 		return repository;
141 	}
142 
143 	protected synchronized Repository getRepository(String workspaceName) {
144 		return getDefaultRepository();
145 	}
146 
147 	/**
148 	 * Logs in to the default workspace, creates the required workspace, logs out,
149 	 * logs in to the required workspace.
150 	 */
151 	protected Session createWorkspaceAndLogsIn(Credentials credentials, String workspaceName)
152 			throws RepositoryException {
153 		if (workspaceName == null)
154 			throw new ArgeoJcrException("No workspace specified.");
155 		Session session = getRepository(workspaceName).login(credentials);
156 		session.getWorkspace().createWorkspace(workspaceName);
157 		session.logout();
158 		return getRepository(workspaceName).login(credentials, workspaceName);
159 	}
160 
161 	public boolean isStandardDescriptor(String key) {
162 		return getRepository().isStandardDescriptor(key);
163 	}
164 
165 	public boolean isSingleValueDescriptor(String key) {
166 		if (additionalDescriptors.containsKey(key))
167 			return true;
168 		return getRepository().isSingleValueDescriptor(key);
169 	}
170 
171 	public Value getDescriptorValue(String key) {
172 		if (additionalDescriptors.containsKey(key))
173 			return new StrValue(additionalDescriptors.get(key));
174 		return getRepository().getDescriptorValue(key);
175 	}
176 
177 	public Value[] getDescriptorValues(String key) {
178 		return getRepository().getDescriptorValues(key);
179 	}
180 
181 	public synchronized void setRepository(Repository repository) {
182 		this.repository = repository;
183 	}
184 
185 	public void setAutocreateWorkspaces(Boolean autocreateWorkspaces) {
186 		this.autocreateWorkspaces = autocreateWorkspaces;
187 	}
188 
189 	protected static class StrValue implements Value {
190 		private final String str;
191 
192 		public StrValue(String str) {
193 			this.str = str;
194 		}
195 
196 		@Override
197 		public String getString() throws ValueFormatException, IllegalStateException, RepositoryException {
198 			return str;
199 		}
200 
201 		@Override
202 		public InputStream getStream() throws RepositoryException {
203 			throw new UnsupportedOperationException();
204 		}
205 
206 		@Override
207 		public Binary getBinary() throws RepositoryException {
208 			throw new UnsupportedOperationException();
209 		}
210 
211 		@Override
212 		public long getLong() throws ValueFormatException, RepositoryException {
213 			try {
214 				return Long.parseLong(str);
215 			} catch (NumberFormatException e) {
216 				throw new ValueFormatException("Cannot convert", e);
217 			}
218 		}
219 
220 		@Override
221 		public double getDouble() throws ValueFormatException, RepositoryException {
222 			try {
223 				return Double.parseDouble(str);
224 			} catch (NumberFormatException e) {
225 				throw new ValueFormatException("Cannot convert", e);
226 			}
227 		}
228 
229 		@Override
230 		public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
231 			try {
232 				return new BigDecimal(str);
233 			} catch (NumberFormatException e) {
234 				throw new ValueFormatException("Cannot convert", e);
235 			}
236 		}
237 
238 		@Override
239 		public Calendar getDate() throws ValueFormatException, RepositoryException {
240 			throw new UnsupportedOperationException();
241 		}
242 
243 		@Override
244 		public boolean getBoolean() throws ValueFormatException, RepositoryException {
245 			try {
246 				return Boolean.parseBoolean(str);
247 			} catch (NumberFormatException e) {
248 				throw new ValueFormatException("Cannot convert", e);
249 			}
250 		}
251 
252 		@Override
253 		public int getType() {
254 			return PropertyType.STRING;
255 		}
256 
257 	}
258 
259 }