KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > books > publisher > impl > BookPublisherImpl


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
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.outerj.daisy.books.publisher.impl;
17
18 import org.outerj.daisy.books.publisher.BookPublisher;
19 import org.outerj.daisy.books.publisher.PublicationSpec;
20 import org.outerj.daisy.books.publisher.PublicationTypeInfo;
21 import org.outerj.daisy.books.publisher.PublishTaskInfo;
22 import org.outerj.daisy.books.publisher.impl.publicationtype.PublicationTypeBuilder;
23 import org.outerj.daisy.books.store.BookStore;
24 import org.outerj.daisy.books.store.BookInstance;
25 import org.outerj.daisy.books.store.BookAcl;
26 import org.outerj.daisy.books.store.impl.BookAclEvaluator;
27 import org.outerj.daisy.books.store.impl.AclResult;
28 import org.outerj.daisy.frontend.components.wikidatasource.WikiDataSource;
29 import org.outerj.daisy.repository.Repository;
30 import org.outerj.daisy.repository.VariantKey;
31 import org.outerj.daisy.repository.clientimpl.RemoteRepositoryImpl;
32 import org.outerj.daisy.xmlutil.LocalSAXParserFactory;
33 import org.apache.avalon.framework.service.Serviceable;
34 import org.apache.avalon.framework.service.ServiceManager;
35 import org.apache.avalon.framework.service.ServiceException;
36 import org.apache.avalon.framework.context.Contextualizable;
37 import org.apache.avalon.framework.context.Context;
38 import org.apache.avalon.framework.context.ContextException;
39 import org.apache.avalon.framework.thread.ThreadSafe;
40 import org.apache.avalon.framework.logger.LogEnabled;
41 import org.apache.avalon.framework.logger.Logger;
42 import org.apache.avalon.framework.activity.Disposable;
43 import org.apache.excalibur.source.SourceResolver;
44 import org.apache.excalibur.source.Source;
45 import org.apache.cocoon.components.thread.RunnableManager;
46 import org.apache.xmlbeans.XmlOptions;
47 import org.outerx.daisy.x10Bookpubtype.PublicationTypeDocument;
48
49 import java.util.*;
50 import java.io.File JavaDoc;
51 import java.security.SecureRandom JavaDoc;
52 import java.text.DateFormat JavaDoc;
53
54 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
55
56
57 public class BookPublisherImpl implements BookPublisher, Serviceable, Contextualizable, ThreadSafe, LogEnabled, Disposable {
58     private ServiceManager serviceManager;
59     private Context context;
60     private Logger logger;
61     private ConcurrentReaderHashMap activeTasks = new ConcurrentReaderHashMap();
62     private RunnableManager runnableManager;
63
64     public void enableLogging(Logger logger) {
65         this.logger = logger;
66     }
67
68     public void service(ServiceManager serviceManager) throws ServiceException {
69         this.serviceManager = serviceManager;
70         this.runnableManager = (RunnableManager)serviceManager.lookup(RunnableManager.ROLE);
71     }
72
73     public void contextualize(Context context) throws ContextException {
74         this.context = context;
75     }
76
77     public void dispose() {
78         serviceManager.release(runnableManager);
79     }
80
81     public String JavaDoc[] publishBook(Repository repository, VariantKey bookDefinition, long dataBranchId, long dataLanguageId,
82                             String JavaDoc dataVersion, Locale locale, String JavaDoc bookInstanceName, String JavaDoc bookInstanceLabel,
83                             String JavaDoc daisyCocoonPath, String JavaDoc daisyContextPath, PublicationSpec[] specs, BookAcl acl) throws Exception JavaDoc {
84         // check that no two publication output specs have the same name
85
for (int i = 0; i < specs.length; i++) {
86             String JavaDoc name = specs[i].getPublicationOutputName();
87             for (int j = 0; j < specs.length; j++) {
88                 if (i != j && specs[j].getPublicationOutputName().equals(name)) {
89                     throw new RuntimeException JavaDoc("Found duplicate publication name: \"" + name + "\".");
90                 }
91             }
92         }
93
94         // check that the user doens't exclude access for herself with the given ACL
95
AclResult result = BookAclEvaluator.evaluate(acl, repository.getUserId(), repository.getActiveRoleIds());
96         if (!result.canManage())
97             throw new RuntimeException JavaDoc("The specified ACL excludes manage permission for the person starting the publication, which is disallowed.");
98
99         BookStore bookStore = (BookStore)repository.getExtension("BookStore");
100         BookInstance bookInstance = bookStore.createBookInstance(bookInstanceName, bookInstanceLabel);
101         bookInstance.setAcl(acl);
102
103         // Make a clone of the repository object, since it is not thread safe
104
repository = (Repository)((RemoteRepositoryImpl)repository).clone();
105
106         BookPublishTask bookPublishTask = new BookPublishTask(bookDefinition, dataBranchId, dataLanguageId, dataVersion,
107                 locale, specs, bookInstance, daisyContextPath, daisyCocoonPath, repository, serviceManager, context);
108
109         BackgroundTaskExecutor bte = new BackgroundTaskExecutor(bookPublishTask, this, logger, context, serviceManager);
110         synchronized(this) {
111             String JavaDoc taskId = generateTaskId();
112             while (activeTasks.contains(taskId)) {
113                 taskId = generateTaskId();
114             }
115
116             activeTasks.put(taskId, bte);
117             try {
118                 bte.setTaskId(taskId);
119                 runnableManager.execute(bte);
120             } catch (Throwable JavaDoc e) {
121                 activeTasks.remove(taskId);
122                 throw new Exception JavaDoc("Error starting background book publication task.", e);
123             }
124             return new String JavaDoc[] { taskId, bookInstance.getName() };
125         }
126     }
127
128     public String JavaDoc[] getTaskState(String JavaDoc taskId) {
129         BackgroundTaskExecutor bte = (BackgroundTaskExecutor)activeTasks.get(taskId);
130         return bte != null ? bte.getBookPublishTask().getState() : null;
131     }
132
133     public PublishTaskInfo[] getTaskOverview(Locale locale) {
134         List result = new ArrayList();
135         BackgroundTaskExecutor[] executors = (BackgroundTaskExecutor[])activeTasks.values().toArray(new BackgroundTaskExecutor[0]);
136         DateFormat JavaDoc dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
137         for (int i = 0; i < executors.length; i++) {
138             PublishTaskInfo taskInfo = new PublishTaskInfo(executors[i].getTaskId(),
139                     executors[i].getBookPublishTask().getBookInstance().getName(),
140                     executors[i].getBookPublishTask().getRepository().getUserId(),
141                     executors[i].getBookPublishTask().getRepository().getUserDisplayName(),
142                     executors[i].getBookPublishTask().getState(),
143                     dateTimeFormat.format(executors[i].getStarted()));
144             result.add(taskInfo);
145         }
146         return (PublishTaskInfo[])result.toArray(new PublishTaskInfo[result.size()]);
147     }
148
149     /**
150      * Called by a BackgroundTaskExecutor to notify the task has ended.
151      */

152     protected void taskEnded(String JavaDoc taskId) {
153         activeTasks.remove(taskId);
154     }
155
156     private static String JavaDoc generateTaskId() throws Exception JavaDoc {
157         byte[] bytes = new byte[15];
158         SecureRandom JavaDoc random = SecureRandom.getInstance("SHA1PRNG");
159         random.nextBytes(bytes);
160         return toHexString(bytes);
161     }
162
163     private static String JavaDoc toHexString(byte[] b) {
164         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(b.length * 2);
165         for (int i = 0; i < b.length; i++) {
166             sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
167             sb.append(hexChar[b[i] & 0x0f]);
168         }
169         return sb.toString();
170     }
171
172     private final static char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
173
174     public PublicationTypeInfo[] getAvailablePublicationTypes(String JavaDoc daisyContextPath) throws Exception JavaDoc {
175         SourceResolver sourceResolver = null;
176         Source source = null;
177         try {
178             sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE);
179             source = sourceResolver.resolveURI("wikidata:/books/publicationtypes");
180             if (!(source instanceof WikiDataSource)) { //FIXME
181
throw new Exception JavaDoc("Expected a WikiDataSource when resolving the publicationtypes directory.");
182             }
183             WikiDataSource wikiDataSource = (WikiDataSource) source;
184             Collection children = wikiDataSource.getChildren();
185             List result = new ArrayList();
186             XmlOptions xmlOptions = new XmlOptions().setLoadUseXMLReader(LocalSAXParserFactory.newXmlReader());
187             Iterator childIterator = children.iterator();
188             while (childIterator.hasNext()){
189                 WikiDataSource child = (WikiDataSource) childIterator.next();
190                 File JavaDoc publicationTypeXmlFile = new File JavaDoc(child.getFile(), "publicationtype.xml");
191                 if (child.isCollection() && publicationTypeXmlFile.exists()) {
192                     String JavaDoc label = null;
193                     try {
194                         label = PublicationTypeDocument.Factory.parse(publicationTypeXmlFile, xmlOptions).getPublicationType().getLabel();
195                     } catch (Throwable JavaDoc e) {
196                         logger.error("Error parsing publicationtype.xml at " + publicationTypeXmlFile.getAbsolutePath(), e);
197                     }
198                     if (label != null)
199                         result.add(new PublicationTypeInfo(child.getName(), label));
200                 }
201             }
202             return (PublicationTypeInfo[])result.toArray(new PublicationTypeInfo[result.size()]);
203         } finally {
204             if (source != null)
205                 sourceResolver.release(source);
206             if (sourceResolver != null)
207                 serviceManager.release(sourceResolver);
208         }
209     }
210
211     public Map getDefaultProperties(String JavaDoc publicationTypeName, String JavaDoc daisyContextPath) throws Exception JavaDoc {
212         return PublicationTypeBuilder.loadProperties(publicationTypeName, daisyContextPath, serviceManager);
213     }
214 }
215
Popular Tags