1 16 package org.outerj.daisy.books.frontend; 17 18 import org.outerj.daisy.frontend.util.AbstractDaisyApple; 19 import org.outerj.daisy.frontend.util.FormHelper; 20 import org.outerj.daisy.frontend.util.HttpMethodNotAllowedException; 21 import org.outerj.daisy.frontend.util.EncodingUtil; 22 import org.outerj.daisy.frontend.RequestUtil; 23 import org.outerj.daisy.frontend.WikiHelper; 24 import org.outerj.daisy.frontend.PageContext; 25 import org.outerj.daisy.frontend.SkinConfHelper; 26 import org.outerj.daisy.repository.*; 27 import org.outerj.daisy.books.publisher.BookPublisher; 28 import org.outerj.daisy.books.publisher.PublicationSpec; 29 import org.outerj.daisy.books.publisher.PublicationSpecBuilder; 30 import org.outerj.daisy.books.publisher.impl.util.XMLPropertiesHelper; 31 import org.outerj.daisy.books.store.*; 32 import org.outerj.daisy.books.store.impl.AclResult; 33 import org.outerj.daisy.books.store.impl.BookAclEvaluator; 34 import org.apache.cocoon.components.flow.apples.AppleRequest; 35 import org.apache.cocoon.components.flow.apples.AppleResponse; 36 import org.apache.cocoon.environment.Request; 37 import org.apache.cocoon.forms.formmodel.*; 38 import org.apache.cocoon.forms.formmodel.Field; 39 import org.apache.cocoon.forms.FormContext; 40 import org.apache.cocoon.forms.validation.WidgetValidator; 41 import org.apache.cocoon.forms.validation.ValidationErrorAware; 42 import org.apache.cocoon.forms.validation.ValidationError; 43 import org.apache.cocoon.ResourceNotFoundException; 44 import org.apache.avalon.framework.service.Serviceable; 45 import org.apache.avalon.framework.service.ServiceManager; 46 import org.apache.avalon.framework.service.ServiceException; 47 import org.apache.avalon.framework.activity.Disposable; 48 import org.apache.commons.collections.map.ListOrderedMap; 49 50 import java.text.DateFormat ; 51 import java.text.SimpleDateFormat ; 52 import java.util.*; 53 import java.io.InputStream ; 54 import java.net.URLEncoder ; 55 56 public class CreateBookInstanceApple extends AbstractDaisyApple implements Serviceable, Disposable { 57 private boolean init = false; 58 private boolean paramsFormOk = false; 59 private boolean publicationsFormOk = false; 60 private Form paramsForm; 61 private Form publicationsForm; 62 private Form aclForm; 63 private ServiceManager serviceManager; 64 private Repository repository; 65 private BookPublisher bookPublisher; 66 private Locale locale; 67 private VariantKey bookDefinition; 68 69 public void service(ServiceManager serviceManager) throws ServiceException { 70 this.serviceManager = serviceManager; 71 this.bookPublisher = (BookPublisher)serviceManager.lookup(BookPublisher.ROLE); 72 } 73 74 public void dispose() { 75 serviceManager.release(bookPublisher); 76 } 77 78 protected void processInternal(AppleRequest appleRequest, AppleResponse appleResponse) throws Exception { 79 Request request = appleRequest.getCocoonRequest(); 80 81 if (!init) { 82 repository = WikiHelper.getRepository(request, serviceManager); 83 if (repository.isInRole("guest") && repository.getActiveRoleIds().length == 1) { 84 throw new Exception ("Users in the guest role are not allowed to publish books."); 85 } 86 String daisyContextPath = WikiHelper.getDaisyContextPath(request); 87 88 long bookDefinitionDocumentId = RequestUtil.getLongParameter(request, "bookDefinitionDocumentId"); 89 long bookDefinitionBranchId = RequestUtil.getLongParameter(request, "bookDefinitionBranchId"); 90 long bookDefinitionLanguageId = RequestUtil.getLongParameter(request, "bookDefinitionLanguageId"); 91 bookDefinition = new VariantKey(bookDefinitionDocumentId, bookDefinitionBranchId, bookDefinitionLanguageId); 92 93 97 Document bookDefDoc = repository.getDocument(bookDefinitionDocumentId, bookDefinitionBranchId, bookDefinitionLanguageId, false); 98 Version bookDefDocVersion = bookDefDoc.getLiveVersion(); 99 if (bookDefDocVersion == null) 100 throw new Exception ("Book definition does not have a live version."); 101 String bookDefName = bookDefDocVersion.getDocumentName(); 102 String bookDefBranchName = repository.getVariantManager().getBranch(bookDefinitionBranchId, false).getName(); 103 String bookDefLanguageName = repository.getVariantManager().getLanguage(bookDefinitionLanguageId, false).getName(); 104 105 paramsForm = FormHelper.createForm(serviceManager, "resources/form/bookinstanceparams_definition.xml"); 106 paramsForm.getChild("bookDefinitionName").setValue(bookDefName); 107 paramsForm.getChild("bookDefinitionId").setValue(new Long (bookDefinitionDocumentId)); 108 paramsForm.getChild("bookDefinitionBranchName").setValue(bookDefBranchName); 109 paramsForm.getChild("bookDefinitionLanguageName").setValue(bookDefLanguageName); 110 111 locale = WikiHelper.getLocale(request); 112 SimpleDateFormat dateFormat = (SimpleDateFormat )DateFormat.getDateTimeInstance(); 114 dateFormat.applyPattern("yyyyMMdd-HHmmss"); 115 String date = dateFormat.format(new Date()); 116 String defaultBookInstanceName = bookDefName + "--" + date; 117 defaultBookInstanceName = defaultBookInstanceName.toLowerCase(); 118 defaultBookInstanceName = BookStoreUtil.fixIllegalFileNameCharacters(defaultBookInstanceName); 119 String defaultBookInstanceLabel = bookDefName + " -- " + date; 120 paramsForm.getChild("bookInstanceName").setValue(defaultBookInstanceName); 121 paramsForm.getChild("bookInstanceName").addValidator(new BookIntanceNameValidator()); 122 paramsForm.getChild("bookInstanceLabel").setValue(defaultBookInstanceLabel); 123 124 Field dataBranchIdField = (Field)paramsForm.getChild("dataBranchId"); 125 dataBranchIdField.setValue(new Long (bookDefinitionBranchId)); 126 dataBranchIdField.setSelectionList(repository.getVariantManager().getAllBranches(false).getArray(), "id", "name"); 127 128 Field dataLanguageIdField = (Field)paramsForm.getChild("dataLanguageId"); 129 dataLanguageIdField.setValue(new Long (bookDefinitionLanguageId)); 130 dataLanguageIdField.setSelectionList(repository.getVariantManager().getAllLanguages(false).getArray(), "id", "name"); 131 132 paramsForm.getChild("dataVersion").setValue("live"); 133 Map bookMetadata = getBookMetaData(bookDefDocVersion); 134 String locale = bookMetadata.containsKey("locale") ? (String )bookMetadata.get("locale") : "en-US"; 135 paramsForm.getChild("locale").setValue(locale); 136 137 publicationsForm = FormHelper.createForm(serviceManager, "resources/form/selectpublicationtypes_definition.xml"); 141 publicationsForm.setAttribute("publications-required", Boolean.TRUE); 142 publicationsForm.getChild("editmode").setValue("gui"); 143 publicationsForm.getChild("editmode").setState(WidgetState.INVISIBLE); 144 PublicationTypesFormHelper.initPublicationsForm(publicationsForm, serviceManager, daisyContextPath); 145 if (bookDefDoc.hasPart("BookPublicationsDefault")) { 146 PublicationSpec[] specs = PublicationSpecBuilder.build(bookDefDoc.getPart("BookPublicationsDefault").getDataStream()); 147 PublicationTypesFormHelper.loadPublicationSpecs(publicationsForm, specs, serviceManager, daisyContextPath); 148 } 149 150 aclForm = FormHelper.createForm(serviceManager, "resources/form/bookacl_definition.xml"); 154 aclForm.getChild("editmode").setValue("gui"); 155 aclForm.getChild("editmode").setState(WidgetState.INVISIBLE); 156 initAclForm(bookDefDocVersion); 157 BookAclEditorApple.annotateAclSubjectValues(aclForm, repository); 158 159 init = true; 163 appleResponse.redirectTo(EncodingUtil.encodePath(getParamsPath())); 164 return; 165 } 166 167 String resource = appleRequest.getSitemapParameter("resource"); 168 if (resource == null) { 169 throw new Exception ("Missing 'resource' sitemap parameter."); 170 } else if (resource.equals("params")) { 171 if (request.getMethod().equals("GET")) { 172 showParamsForm(appleResponse); 173 } else if (request.getMethod().equals("POST")) { 174 boolean finished = paramsForm.process(new FormContext(request, locale)); 175 if (finished) { 176 paramsFormOk = true; 177 appleResponse.redirectTo(EncodingUtil.encodePath(getPublicationTypesPath())); 178 } else { 179 paramsFormOk = false; 180 showParamsForm(appleResponse); 181 } 182 } else { 183 throw new HttpMethodNotAllowedException(request.getMethod()); 184 } 185 } else if (resource.equals("publicationtypes")) { 186 if (!paramsFormOk) { 187 appleResponse.redirectTo(EncodingUtil.encodePath(getParamsPath())); 188 } else if (request.getMethod().equals("GET")) { 189 showPublicationTypesForm(appleResponse); 190 } else if (request.getMethod().equals("POST")) { 191 boolean finished = publicationsForm.process(new FormContext(request, locale)); 192 if (publicationsForm.getSubmitWidget() == publicationsForm.getChild("goBack")) { 193 publicationsFormOk = finished; 194 appleResponse.redirectTo(EncodingUtil.encodePath(getParamsPath())); 195 } else if (finished) { 196 publicationsFormOk = true; 197 appleResponse.redirectTo(EncodingUtil.encodePath(getAclPath())); 198 } else { 199 publicationsFormOk = false; 200 showPublicationTypesForm(appleResponse); 201 } 202 } else { 203 throw new HttpMethodNotAllowedException(request.getMethod()); 204 } 205 } else if (resource.equals("acl")) { 206 if (!paramsFormOk) { 207 appleResponse.redirectTo(getParamsPath()); 208 } else if (!publicationsFormOk) { 209 appleResponse.redirectTo(getPublicationTypesPath()); 210 } else if (request.getMethod().equals("GET")) { 211 showAclForm(appleResponse); 212 } else if (request.getMethod().equals("POST")) { 213 boolean finished = aclForm.process(new FormContext(request, locale)); 214 if (aclForm.getSubmitWidget() == aclForm.getChild("goBack")) { 215 appleResponse.redirectTo(getPublicationTypesPath()); 216 } else if (finished) { 217 String [] taskIdAndInstanceName = publishBook(request); 218 Map viewData = new HashMap(); 219 viewData.put("pageContext", new PageContext(getMountPoint(), repository, getLayoutType(), getSkin(), SkinConfHelper.getGlobalSkinConf(serviceManager), getContext())); 220 viewData.put("taskId", taskIdAndInstanceName[0]); 221 viewData.put("bookInstanceName", URLEncoder.encode(taskIdAndInstanceName[1], "UTF-8")); 222 appleResponse.sendPage("Message-bookpublished-Pipe", viewData); 223 } else { 224 showAclForm(appleResponse); 225 } 226 } else { 227 throw new HttpMethodNotAllowedException(request.getMethod()); 228 } 229 } else { 230 throw new ResourceNotFoundException(resource); 231 } 232 } 233 234 private String [] publishBook(Request request) throws Exception { 235 long dataBranchId = ((Long )paramsForm.getChild("dataBranchId").getValue()).longValue(); 236 long dataLanguageId = ((Long )paramsForm.getChild("dataLanguageId").getValue()).longValue(); 237 String dataVersion = (String )paramsForm.getChild("dataVersion").getValue(); 238 Locale locale = LocaleHelper.parseLocale((String )paramsForm.getChild("locale").getValue()); 239 String bookInstanceName = (String )paramsForm.getChild("bookInstanceName").getValue(); 240 String bookInstanceLabel = (String )paramsForm.getChild("bookInstanceLabel").getValue(); 241 String daisyCocoonPath = WikiHelper.getDaisyCocoonPath(request); 242 String daisyContextPath = WikiHelper.getDaisyContextPath(request); 243 244 Repeater publicationsRepeater = (Repeater)publicationsForm.lookupWidget("editors/gui/publications"); 245 PublicationSpec[] specs = new PublicationSpec[publicationsRepeater.getSize()]; 246 for (int i = 0; i < publicationsRepeater.getSize(); i++) { 247 Repeater.RepeaterRow row = publicationsRepeater.getRow(i); 248 String publicationTypeName = (String )row.getChild("typeName").getValue(); 249 String outputName = (String )row.getChild("outputName").getValue(); 250 String outputLabel = (String )row.getChild("outputLabel").getValue(); 251 Map properties = getProperties((Repeater)row.getChild("properties")); 252 specs[i] = new PublicationSpec(publicationTypeName, outputName, outputLabel, properties); 253 } 254 255 BookAcl acl = BookAclEditorApple.getBookAcl(aclForm); 256 257 return bookPublisher.publishBook(repository, bookDefinition, dataBranchId, dataLanguageId, dataVersion, locale, 258 bookInstanceName, bookInstanceLabel, daisyCocoonPath, daisyContextPath, specs, acl); 259 } 260 261 private Map getProperties(Repeater propertiesRepeater) { 262 Map properties = new ListOrderedMap(); 263 for (int i = 0; i < propertiesRepeater.getSize(); i++) { 264 Repeater.RepeaterRow row = propertiesRepeater.getRow(i); 265 String name = (String )row.getChild("name").getValue(); 266 if (name != null) 267 name = name.trim(); 268 String value = (String )row.getChild("value").getValue(); 269 if (name != null && name.length() > 0) { 270 properties.put(name, value == null ? "": value); 271 } 272 } 273 return properties; 274 } 275 276 private void showParamsForm(AppleResponse appleResponse) throws Exception { 277 Map viewData = new HashMap(); 278 viewData.put("locale", locale); 279 viewData.put("CocoonFormsInstance", paramsForm); 280 viewData.put("pageContext", new PageContext(getMountPoint(), repository, getLayoutType(), getSkin(), SkinConfHelper.getGlobalSkinConf(serviceManager), getContext())); 281 appleResponse.sendPage("Form-bookinstanceparams-Pipe", viewData); 282 } 283 284 private void showPublicationTypesForm(AppleResponse appleResponse) throws Exception { 285 Map viewData = new HashMap(); 286 viewData.put("locale", locale); 287 viewData.put("CocoonFormsInstance", publicationsForm); 288 viewData.put("pageContext", new PageContext(getMountPoint(), repository, getLayoutType(), getSkin(), SkinConfHelper.getGlobalSkinConf(serviceManager), getContext())); 289 appleResponse.sendPage("Form-selectpublicationtypes-Pipe", viewData); 290 } 291 292 private void showAclForm(AppleResponse appleResponse) throws Exception { 293 Map viewData = new HashMap(); 294 viewData.put("inBookPublishWizard", Boolean.TRUE); 295 viewData.put("locale", locale); 296 viewData.put("CocoonFormsInstance", aclForm); 297 viewData.put("pageContext", new PageContext(getMountPoint(), repository, getLayoutType(), getSkin(), SkinConfHelper.getGlobalSkinConf(serviceManager), getContext())); 298 appleResponse.sendPage("Form-bookacl-Pipe", viewData); 299 } 300 301 private String getParamsPath() { 302 return getMountPoint() + "/books/createBookInstance/" + getContinuationId() + "/params"; 303 } 304 305 private String getPublicationTypesPath() { 306 return getMountPoint() + "/books/createBookInstance/" + getContinuationId() + "/publicationtypes"; 307 } 308 309 private String getAclPath() { 310 return getMountPoint() + "/books/createBookInstance/" + getContinuationId() + "/acl"; 311 } 312 313 314 private void initAclForm(Version bookDefDoc) throws Exception { 315 BookAclEditorApple.initForm(aclForm, repository); 316 317 Repeater aclEntriesRepeater = (Repeater)aclForm.lookupWidget("editors/gui/entries"); 318 319 if (bookDefDoc.hasPart("BookAclDefault")) { 320 BookAcl bookAcl = BookAclBuilder.build(bookDefDoc.getPart("BookAclDefault").getDataStream()); 321 BookAclEditorApple.load(aclForm, bookAcl); 322 323 AclResult result = BookAclEvaluator.evaluate(bookAcl, repository.getUserId(), repository.getActiveRoleIds()); 326 if (!result.canManage()) { 327 Repeater.RepeaterRow row = aclEntriesRepeater.addRow(); 328 row.getChild("subjectType").setValue(BookAclSubjectType.USER); 329 row.getChild("subjectValue").setValue(new Long (repository.getUserId())); 330 row.getChild("readPerm").setValue(BookAclActionType.GRANT); 331 row.getChild("managePerm").setValue(BookAclActionType.GRANT); 332 } 333 } else { 334 Repeater.RepeaterRow row = aclEntriesRepeater.addRow(); 336 row.getChild("subjectType").setValue(BookAclSubjectType.USER); 337 row.getChild("subjectValue").setValue(new Long (repository.getUserId())); 338 row.getChild("readPerm").setValue(BookAclActionType.GRANT); 339 row.getChild("managePerm").setValue(BookAclActionType.GRANT); 340 } 341 } 342 343 private Map getBookMetaData(Version bookDefDocVersion) throws Exception { 344 if (bookDefDocVersion.hasPart("BookMetadata")) { 345 InputStream is = null; 346 try { 347 is = bookDefDocVersion.getPart("BookMetadata").getDataStream(); 348 return XMLPropertiesHelper.load(is, "metadata"); 349 } finally { 350 if (is != null) 351 is.close(); 352 } 353 } else { 354 return new HashMap(); 355 } 356 } 357 358 private class BookIntanceNameValidator implements WidgetValidator { 359 public boolean validate(Widget widget) { 360 String name = (String )widget.getValue(); 361 BookStore bookStore = (BookStore)repository.getExtension("BookStore"); 362 if (bookStore.existsBookInstance(name)) { 363 ((ValidationErrorAware)widget).setValidationError(new ValidationError("bookip.duplicate-instance-name", true)); 364 return false; 365 } 366 return true; 367 } 368 } 369 } 370 | Popular Tags |