KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > content > AbstractContent


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.content;
18
19 import java.io.IOException JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21 import java.nio.ByteBuffer JavaDoc;
22 import java.nio.MappedByteBuffer JavaDoc;
23 import java.nio.channels.FileChannel JavaDoc;
24 import java.nio.channels.FileLock JavaDoc;
25 import java.nio.channels.ReadableByteChannel JavaDoc;
26 import java.nio.channels.WritableByteChannel JavaDoc;
27 import java.util.List JavaDoc;
28
29 import org.alfresco.error.AlfrescoRuntimeException;
30 import org.alfresco.repo.transaction.TransactionUtil;
31 import org.alfresco.service.cmr.repository.Content;
32 import org.alfresco.service.cmr.repository.ContentStreamListener;
33 import org.alfresco.service.transaction.TransactionService;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.springframework.aop.AfterReturningAdvice;
37
38 /**
39  * Provides basic information for <tt>Content</tt>.
40  *
41  * @author Derek Hulley
42  */

43 public abstract class AbstractContent implements Content
44 {
45     private static Log logger = LogFactory.getLog(AbstractContent.class);
46     
47     /** when set, ensures that listeners are executed within a transaction */
48     private TransactionService transactionService;
49     
50     private String JavaDoc contentUrl;
51     private String JavaDoc mimetype;
52     private String JavaDoc encoding;
53
54     /**
55      * @param contentUrl the content URL
56      */

57     protected AbstractContent(String JavaDoc contentUrl)
58     {
59         if (contentUrl == null || contentUrl.length() == 0)
60         {
61             throw new IllegalArgumentException JavaDoc("contentUrl must be a valid String");
62         }
63         this.contentUrl = contentUrl;
64     }
65
66     /**
67      * Provides access to transactions for implementing classes
68      *
69      * @return Returns a source of user transactions
70      */

71     protected TransactionService getTransactionService()
72     {
73         return transactionService;
74     }
75
76     public void setTransactionService(TransactionService transactionService)
77     {
78         this.transactionService = transactionService;
79     }
80
81     public String JavaDoc toString()
82     {
83         StringBuilder JavaDoc sb = new StringBuilder JavaDoc(100);
84         sb.append("Content")
85           .append("[ url=").append(contentUrl)
86           .append(", mimetype=").append(mimetype)
87           .append(", encoding=").append(encoding)
88           .append("]");
89         return sb.toString();
90     }
91     
92     public String JavaDoc getContentUrl()
93     {
94         return contentUrl;
95     }
96     
97     public String JavaDoc getMimetype()
98     {
99         return mimetype;
100     }
101
102     /**
103      * @param mimetype the underlying content's mimetype - null if unknown
104      */

105     public void setMimetype(String JavaDoc mimetype)
106     {
107         this.mimetype = mimetype;
108     }
109     
110     public String JavaDoc getEncoding()
111     {
112         return encoding;
113     }
114
115     /**
116      * @param encoding the underlying content's encoding - null if unknown
117      */

118     public void setEncoding(String JavaDoc encoding)
119     {
120         this.encoding = encoding;
121     }
122     
123     /**
124      * Advise that listens for the completion of specific methods on the
125      * {@link java.nio.channels.ByteChannel} interface.
126      *
127      * @author Derek Hulley
128      */

129     protected class ByteChannelCallbackAdvise implements AfterReturningAdvice
130     {
131         private List JavaDoc<ContentStreamListener> listeners;
132
133         public ByteChannelCallbackAdvise(List JavaDoc<ContentStreamListener> listeners)
134         {
135             this.listeners = listeners;
136         }
137         
138         /**
139          * Provides transactional callbacks to the listeners
140          */

141         public void afterReturning(Object JavaDoc returnValue, Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc target) throws Throwable JavaDoc
142         {
143             // check for specific events
144
if (method.getName().equals("close"))
145             {
146                 fireChannelClosed();
147             }
148         }
149         
150         private void fireChannelClosed()
151         {
152             if (listeners.size() == 0)
153             {
154                 // nothing to do
155
return;
156             }
157             // ensure that we are in a transaction
158
if (transactionService == null)
159             {
160                 throw new AlfrescoRuntimeException("A transaction service is required when there are listeners present");
161             }
162             TransactionUtil.TransactionWork work = new TransactionUtil.TransactionWork()
163                     {
164                         public Object JavaDoc doWork()
165                         {
166                             // call the listeners
167
for (ContentStreamListener listener : listeners)
168                             {
169                                 listener.contentStreamClosed();
170                             }
171                             return null;
172                         }
173                     };
174             TransactionUtil.executeInUserTransaction(transactionService, work);
175             // done
176
if (logger.isDebugEnabled())
177             {
178                 logger.debug("Content listeners called: close");
179             }
180         }
181     }
182     
183     /**
184      * Wraps a <code>FileChannel</code> to provide callbacks to listeners when the
185      * channel is {@link java.nio.channels.Channel#close() closed}.
186      *
187      * @author Derek Hulley
188      */

189     protected class CallbackFileChannel extends FileChannel JavaDoc
190     {
191         /** the channel to route all calls to */
192         private FileChannel JavaDoc delegate;
193         /** listeners waiting for the stream close */
194         private List JavaDoc<ContentStreamListener> listeners;
195
196         /**
197          * @param delegate the channel that will perform the work
198          * @param listeners listeners for events coming from this channel
199          */

200         public CallbackFileChannel(
201                 FileChannel JavaDoc delegate,
202                 List JavaDoc<ContentStreamListener> listeners)
203         {
204             if (delegate == null)
205             {
206                 throw new IllegalArgumentException JavaDoc("FileChannel delegate is required");
207             }
208             if (delegate instanceof CallbackFileChannel)
209             {
210                 throw new IllegalArgumentException JavaDoc("FileChannel delegate may not be a CallbackFileChannel");
211             }
212             
213             this.delegate = delegate;
214             this.listeners = listeners;
215         }
216         
217         /**
218          * Closes the channel and makes the callbacks to the listeners
219          */

220         @Override JavaDoc
221         protected void implCloseChannel() throws IOException JavaDoc
222         {
223             delegate.close();
224             fireChannelClosed();
225         }
226
227         /**
228          * Helper method to notify stream listeners
229          */

230         private void fireChannelClosed()
231         {
232             if (listeners.size() == 0)
233             {
234                 // nothing to do
235
return;
236             }
237             // ensure that we are in a transaction
238
if (transactionService == null)
239             {
240                 throw new AlfrescoRuntimeException("A transaction service is required when there are listeners present");
241             }
242             TransactionUtil.TransactionWork work = new TransactionUtil.TransactionWork()
243                     {
244                         public Object JavaDoc doWork()
245                         {
246                             // call the listeners
247
for (ContentStreamListener listener : listeners)
248                             {
249                                 listener.contentStreamClosed();
250                             }
251                             return null;
252                         }
253                     };
254             TransactionUtil.executeInUserTransaction(transactionService, work);
255             // done
256
if (logger.isDebugEnabled())
257             {
258                 logger.debug("Content listeners called: close");
259             }
260         }
261
262         @Override JavaDoc
263         public void force(boolean metaData) throws IOException JavaDoc
264         {
265             delegate.force(metaData);
266         }
267
268         @Override JavaDoc
269         public FileLock JavaDoc lock(long position, long size, boolean shared) throws IOException JavaDoc
270         {
271             return delegate.lock(position, size, shared);
272         }
273
274         @Override JavaDoc
275         public MappedByteBuffer JavaDoc map(MapMode mode, long position, long size) throws IOException JavaDoc
276         {
277             return delegate.map(mode, position, size);
278         }
279
280         @Override JavaDoc
281         public long position() throws IOException JavaDoc
282         {
283             return delegate.position();
284         }
285
286         @Override JavaDoc
287         public FileChannel JavaDoc position(long newPosition) throws IOException JavaDoc
288         {
289             return delegate.position(newPosition);
290         }
291
292         @Override JavaDoc
293         public int read(ByteBuffer JavaDoc dst) throws IOException JavaDoc
294         {
295             return delegate.read(dst);
296         }
297
298         @Override JavaDoc
299         public int read(ByteBuffer JavaDoc dst, long position) throws IOException JavaDoc
300         {
301             return delegate.read(dst, position);
302         }
303
304         @Override JavaDoc
305         public long read(ByteBuffer JavaDoc[] dsts, int offset, int length) throws IOException JavaDoc
306         {
307             return delegate.read(dsts, offset, length);
308         }
309
310         @Override JavaDoc
311         public long size() throws IOException JavaDoc
312         {
313             return delegate.size();
314         }
315
316         @Override JavaDoc
317         public long transferFrom(ReadableByteChannel JavaDoc src, long position, long count) throws IOException JavaDoc
318         {
319             return delegate.transferFrom(src, position, count);
320         }
321
322         @Override JavaDoc
323         public long transferTo(long position, long count, WritableByteChannel JavaDoc target) throws IOException JavaDoc
324         {
325             return delegate.transferTo(position, count, target);
326         }
327
328         @Override JavaDoc
329         public FileChannel JavaDoc truncate(long size) throws IOException JavaDoc
330         {
331             return delegate.truncate(size);
332         }
333
334         @Override JavaDoc
335         public FileLock JavaDoc tryLock(long position, long size, boolean shared) throws IOException JavaDoc
336         {
337             return delegate.tryLock(position, size, shared);
338         }
339
340         @Override JavaDoc
341         public int write(ByteBuffer JavaDoc src) throws IOException JavaDoc
342         {
343             return delegate.write(src);
344         }
345
346         @Override JavaDoc
347         public int write(ByteBuffer JavaDoc src, long position) throws IOException JavaDoc
348         {
349             return delegate.write(src, position);
350         }
351
352         @Override JavaDoc
353         public long write(ByteBuffer JavaDoc[] srcs, int offset, int length) throws IOException JavaDoc
354         {
355             return delegate.write(srcs, offset, length);
356         }
357     }
358 }
359
Popular Tags