1 16 package org.outerj.daisy.books.frontend; 17 18 import org.outerj.daisy.frontend.util.AbstractDaisyApple; 19 import org.outerj.daisy.frontend.util.HttpMethodNotAllowedException; 20 import org.outerj.daisy.frontend.util.EncodingUtil; 21 import org.outerj.daisy.frontend.WikiHelper; 22 import org.outerj.daisy.frontend.PageContext; 23 import org.outerj.daisy.frontend.SkinConfHelper; 24 import org.outerj.daisy.frontend.RequestUtil; 25 import org.outerj.daisy.repository.Repository; 26 import org.outerj.daisy.repository.RepositoryException; 27 import org.outerj.daisy.repository.user.UserManager; 28 import org.outerj.daisy.books.store.*; 29 import org.outerj.daisy.books.publisher.impl.BookInstanceLayout; 30 import org.apache.cocoon.components.flow.apples.StatelessAppleController; 31 import org.apache.cocoon.components.flow.apples.AppleRequest; 32 import org.apache.cocoon.components.flow.apples.AppleResponse; 33 import org.apache.cocoon.environment.Request; 34 import org.apache.cocoon.xml.AttributesImpl; 35 import org.apache.cocoon.xml.EmbeddedXMLPipe; 36 import org.apache.cocoon.xml.SaxBuffer; 37 import org.apache.avalon.framework.service.Serviceable; 38 import org.apache.avalon.framework.service.ServiceManager; 39 import org.apache.avalon.framework.service.ServiceException; 40 import org.apache.xmlbeans.XmlCursor; 41 import org.xml.sax.ContentHandler ; 42 import org.xml.sax.SAXException ; 43 import org.outerx.daisy.x10Bookstoremeta.BookInstanceMetaDataDocument; 44 45 import java.util.*; 46 import java.text.DateFormat ; 47 48 public class ManageBookInstancesApple extends AbstractDaisyApple implements StatelessAppleController, Serviceable { 49 private ServiceManager serviceManager; 50 private DateFormat dateFormat; 51 private UserManager userManager; 52 53 public void service(ServiceManager serviceManager) throws ServiceException { 54 this.serviceManager = serviceManager; 55 } 56 57 protected void processInternal(AppleRequest appleRequest, AppleResponse appleResponse) throws Exception { 58 Request request = appleRequest.getCocoonRequest(); 59 Repository repository = WikiHelper.getRepository(request, serviceManager); 60 String bookInstanceName = appleRequest.getSitemapParameter("bookInstanceName"); 61 BookStore bookStore = (BookStore)repository.getExtension("BookStore"); 62 63 if (bookInstanceName == null) { if (request.getMethod().equals("GET")) { 65 Locale locale = WikiHelper.getLocale(request); 67 this.dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale); 68 this.userManager = repository.getUserManager(); 69 Collection bookInstances = bookStore.getBookInstances(); 70 BookGroup group = buildHierarchicalBookInstanceIndex(bookInstances); 71 SaxBuffer hierarchicalBookInstanceIndex = new SaxBuffer(); 72 group.generateSaxFragment(hierarchicalBookInstanceIndex); 73 74 String mountPoint = WikiHelper.getMountPoint(request); 75 PageContext pageContext = new PageContext(mountPoint, repository, getLayoutType(), getSkin(), SkinConfHelper.getGlobalSkinConf(serviceManager), getContext()); 76 Map viewData = new HashMap(); 77 viewData.put("pageContext", pageContext); 78 viewData.put("hierarchicalBookInstanceIndex", hierarchicalBookInstanceIndex); 79 80 appleResponse.sendPage("BookInstanceManagementPipe", viewData); 81 } else { 82 throw new HttpMethodNotAllowedException(request.getMethod()); 83 } 84 } else { 85 if (request.getMethod().equals("POST")) { 86 String action = request.getParameter("action"); 87 if (action == null) { 88 throw new Exception ("Missing 'action' request parameter."); 89 } else if (action.equals("delete")) { 90 bookStore.deleteBookInstance(bookInstanceName); 91 appleResponse.redirectTo(EncodingUtil.encodePath(getMountPoint() + "/books/")); 92 } else if (action.equals("changeLabel")) { 93 String newLabel = RequestUtil.getStringParameter(request, "newLabel"); 94 if (newLabel.trim().length() == 0) 95 throw new Exception ("Cannot change book instance label: new label is all whitespace."); 96 BookInstance bookInstance = bookStore.getBookInstance(bookInstanceName); 97 bookInstance.lock(); 98 try { 99 BookInstanceMetaData metadata = bookInstance.getMetaData(); 100 metadata.setLabel(newLabel); 101 bookInstance.setMetaData(metadata); 102 } finally { 103 bookInstance.unlock(); 104 } 105 String returnTo = request.getParameter("returnTo"); 106 appleResponse.redirectTo(returnTo != null? returnTo : getMountPoint() + "/books/"); 107 } else if (action.equals("changeName")) { 108 String newName = RequestUtil.getStringParameter(request, "newName"); 109 if (newName.trim().length() == 0) 110 throw new Exception ("Cannot change book instance name: new name is all whitespace."); 111 bookStore.renameBookInstance(bookInstanceName, newName); 112 String returnTo = request.getParameter("returnTo"); 113 appleResponse.redirectTo(returnTo != null? returnTo : getMountPoint() + "/books/"); 114 } else if (action.equals("changePublicationLabel")) { 115 String publicationName = RequestUtil.getStringParameter(request, "publicationName"); 116 String newLabel = RequestUtil.getStringParameter(request, "newLabel"); 117 if (newLabel.trim().length() == 0) 118 throw new Exception ("Cannot change publication label: new label is all whitespace."); 119 BookInstance bookInstance = bookStore.getBookInstance(bookInstanceName); 120 bookInstance.lock(); 121 try { 122 PublicationInfo[] publicationInfos = bookInstance.getPublicationsInfo().getInfos(); 123 PublicationInfo[] resultPublicationInfos = new PublicationInfo[publicationInfos.length]; 124 boolean found = false; 125 for (int i = 0; i < publicationInfos.length; i++) { 126 if (publicationInfos[i].getName().equals(publicationName)) { 127 resultPublicationInfos[i] = new PublicationInfo(publicationInfos[i].getName(), 128 newLabel, publicationInfos[i].getStartResource(), publicationInfos[i].getBookPackage(), 129 publicationInfos[i].getPublishedBy(), publicationInfos[i].getPublishedOn()); 130 found = true; 131 } else { 132 resultPublicationInfos[i] = publicationInfos[i]; 133 } 134 } 135 if (!found) 136 throw new Exception ("There is no publication with name " + publicationName); 137 bookInstance.setPublications(new PublicationsInfo(resultPublicationInfos)); 138 } finally { 139 bookInstance.unlock(); 140 } 141 String returnTo = request.getParameter("returnTo"); 142 appleResponse.redirectTo(returnTo != null? returnTo : getMountPoint() + "/books/"); 143 } else if (action.equals("changePublicationName")) { 144 String publicationName = RequestUtil.getStringParameter(request, "publicationName"); 145 String newName = RequestUtil.getStringParameter(request, "newName"); 146 if (newName.trim().length() == 0) 147 throw new Exception ("Cannot change publication label: new name is all whitespace."); 148 String error = BookStoreUtil.isValidBookInstanceName(newName); 150 if (error != null) 151 throw new Exception (error); 152 BookInstance bookInstance = bookStore.getBookInstance(bookInstanceName); 153 bookInstance.lock(); 154 try { 155 boolean success = bookInstance.rename(BookInstanceLayout.getPublicationOutputPath(publicationName), newName); 156 if (!success) 157 throw new Exception ("Rename failed, maybe there is another publication with the name \"" + newName + "\"?"); 158 PublicationInfo[] publicationInfos = bookInstance.getPublicationsInfo().getInfos(); 159 PublicationInfo[] resultPublicationInfos = new PublicationInfo[publicationInfos.length]; 160 boolean found = false; 161 for (int i = 0; i < publicationInfos.length; i++) { 162 if (publicationInfos[i].getName().equals(publicationName)) { 163 resultPublicationInfos[i] = new PublicationInfo(newName, 164 publicationInfos[i].getLabel(), publicationInfos[i].getStartResource(), 165 publicationInfos[i].getBookPackage(), publicationInfos[i].getPublishedBy(), 166 publicationInfos[i].getPublishedOn()); 167 found = true; 168 } else { 169 resultPublicationInfos[i] = publicationInfos[i]; 170 } 171 } 172 if (!found) 173 throw new Exception ("Error updating publication infos: there is no publication with name " + publicationName); 174 bookInstance.setPublications(new PublicationsInfo(resultPublicationInfos)); 175 } finally { 176 bookInstance.unlock(); 177 } 178 String returnTo = request.getParameter("returnTo"); 179 appleResponse.redirectTo(returnTo != null? returnTo : getMountPoint() + "/books/"); 180 } else { 181 throw new Exception ("Invalid value for 'action' request parameter: \"" + action + "\"."); 182 } 183 } else { 184 throw new HttpMethodNotAllowedException(request.getMethod()); 185 } 186 } 187 } 188 189 private BookGroup buildHierarchicalBookInstanceIndex(Collection bookInstances) { 190 BookGroup rootGroup = new BookGroup("root"); 191 Iterator bookInstancesIt = bookInstances.iterator(); 192 while (bookInstancesIt.hasNext()) { 193 try { 194 BookInstance bookInstance = (BookInstance)bookInstancesIt.next(); 195 BookInstanceMetaData metaData = bookInstance.getMetaData(); 196 BookInstanceMetaDataDocument metaDataDocument = metaData.getXml(); 197 annotateMetaData(metaDataDocument); 198 BookInstanceNode node = new BookInstanceNode(bookInstance.getName(), metaDataDocument, bookInstance.getPublicationsInfo(), bookInstance.canManage()); 199 String path = metaData.getBookPath() != null ? metaData.getBookPath() : ""; 200 BookGroup group = rootGroup.getGroup(path); 201 group.addChild(node); 202 } catch (NonExistingBookInstanceException e) { 203 } catch (BookStoreAccessDeniedException e) { 205 } 207 } 208 return rootGroup; 209 } 210 211 private void annotateMetaData(BookInstanceMetaDataDocument metaDataDocument) { 212 BookInstanceMetaDataDocument.BookInstanceMetaData metaDataXml = metaDataDocument.getBookInstanceMetaData(); 213 String createdOn = dateFormat.format(metaDataXml.getCreatedOn().getTime()); 214 String createdBy; 215 try { 216 createdBy = userManager.getUserDisplayName(metaDataXml.getCreatedBy()); 217 } catch (RepositoryException e) { 218 createdBy = "(error)"; 219 } 220 XmlCursor cursor = metaDataXml.newCursor(); 221 cursor.toNextToken(); 222 cursor.insertAttributeWithValue("createdOnFormatted", createdOn); 223 cursor.insertAttributeWithValue("createdByDisplayName", createdBy); 224 cursor.dispose(); 225 } 226 227 static class BookInstanceNode implements BookGroup.BookGroupChild { 228 private final String name; 229 private final BookInstanceMetaDataDocument metaDataDocument; 230 private final PublicationsInfo publicationsInfo; 231 private final boolean canManage; 232 233 public BookInstanceNode(String name, BookInstanceMetaDataDocument metaData, PublicationsInfo publicationsInfo, boolean canManage) { 234 this.name = name; 235 this.metaDataDocument = metaData; 236 this.publicationsInfo = publicationsInfo; 237 this.canManage = canManage; 238 } 239 240 public int compareTo(Object o) { 241 BookInstanceNode otherBookInstanceNode = (BookInstanceNode)o; 242 return name.compareTo(otherBookInstanceNode.name); 243 } 244 245 public void generateSaxFragment(ContentHandler contentHandler) throws SAXException { 246 EmbeddedXMLPipe consumer = new EmbeddedXMLPipe(contentHandler); 247 248 AttributesImpl bookInstanceAttrs = new AttributesImpl(); 249 bookInstanceAttrs.addCDATAAttribute("name", name); 250 bookInstanceAttrs.addCDATAAttribute("canManage", String.valueOf(canManage)); 251 consumer.startElement("", "bookInstance", "bookInstance", bookInstanceAttrs); 252 metaDataDocument.save(consumer, consumer); 253 publicationsInfo.getXml().save(consumer, consumer); 254 consumer.endElement("", "bookInstance", "bookInstance"); 255 } 256 } 257 } 258 | Popular Tags |