Java tutorial
/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.confluence.plugin.docbook_tools.web; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.activation.MimetypesFileTypeMap; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.confluence.plugin.docbook_tools.docbookimport.DocBookVersion; import org.jboss.confluence.plugin.docbook_tools.docbookimport.DocStructureItem; import org.jboss.confluence.plugin.docbook_tools.docbookimport.DocbookImporter; import org.jboss.confluence.plugin.docbook_tools.utils.ConfluenceUtils; import org.jboss.confluence.plugin.docbook_tools.utils.FileUtils; import com.atlassian.confluence.pages.Attachment; import com.atlassian.confluence.pages.AttachmentManager; import com.atlassian.confluence.pages.Page; import com.atlassian.confluence.pages.PageManager; import com.atlassian.spring.container.ContainerManager; import com.opensymphony.webwork.ServletActionContext; import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper; /** * Web Action used to import DocBook xml in JBoss Documentation form to Confluence. * * @author Vlastimil Elias (velias at redhat dot com) (C) 2011 Red Hat Inc. * @see DocbookImporter */ public class DocbookImportAction extends PageAvareActionBase { private Log logger; private PageManager pageManager; private DocbookImporter importer; private String titlePrefixBase; private String docbookver; private static MimetypesFileTypeMap mtftm = new MimetypesFileTypeMap(); static { // register SVG image type because sometimes not registered String stest = mtftm.getContentType("test.svg"); if (!stest.startsWith("image/")) { mtftm.addMimeTypes("image/svg svg SVG\n"); } } /** * Constructor to initialize. */ public DocbookImportAction() { super(); logger = LogFactory.getLog(getClass()); logger.debug("constructor called"); pageManager = (PageManager) ContainerManager.getComponent("pageManager"); } /** * Form parameter. * * @return the titlePrefixBase */ public String getTitlePrefixBase() { if (titlePrefixBase == null) return ""; return titlePrefixBase; } /** * Form parameter. * * @param titlePrefixBase the titlePrefixBase to set */ public void setTitlePrefixBase(String titlePrefixBase) { if (titlePrefixBase != null) { titlePrefixBase = titlePrefixBase.trim(); if (titlePrefixBase.isEmpty()) titlePrefixBase = null; } this.titlePrefixBase = titlePrefixBase; } /** * Form parameter. * * @return the docbookver */ public String getDocbookver() { return docbookver; } /** * Form parameter. * * @param docbookver the docbookver to set */ public void setDocbookver(String docbookver) { this.docbookver = docbookver; } /** * Called to show import form page. * * @return outcome */ public String configure() { logger.debug("configure called"); if (!hasPermissionForSpace(PERMISSION_EXPORTSPACE)) return "notpermitted"; return "success"; } /** * Called to process import form submit. * * @return outcome */ @SuppressWarnings("rawtypes") public String perform() { logger.debug("perform called"); if (!hasPermissionForSpace(PERMISSION_EXPORTSPACE)) return "notpermitted"; if (!validTitlePrefixBase()) { return "error"; } MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest(); if (multiWrapper.hasErrors()) { Collection errors = multiWrapper.getErrors(); Iterator i = errors.iterator(); while (i.hasNext()) { addActionError((String) i.next()); } return "error"; } File[] files = multiWrapper.getFiles("fileTopp"); String[] fn = multiWrapper.getFileNames("fileTopp"); if ((files == null || files.length == 0)) { addActionError("No file for postprocessing uploaded"); } else { if (!fn[0].endsWith(".zip")) { addActionError("Uploaded file must be .zip"); } else { File workingDir = null; try { importer = new DocbookImporter(); workingDir = FileUtils.prepareWorkingDirectory("import-src-"); FileUtils.unzip(FileUtils.openFileInputStream(files[0]), workingDir); File docBookFileToImport = importer.findMainDocBookBookFile(workingDir); if (docBookFileToImport == null) { addActionError("No main DocBook file containing <book> root element found."); } else { logger.debug("Main DocBook file to process: " + docBookFileToImport.getName()); DocBookVersion docbookVersion = DocBookVersion.DOCBOOK_4_3; if ("5".equals(StringUtils.trimToNull(docbookver))) { docbookVersion = DocBookVersion.DOCBOOK_5_0; } DocStructureItem docToImport = importer.getDocStructure( new FileInputStream(docBookFileToImport), docBookFileToImport.toURI().toString(), docbookVersion); if (validateReferencedLocalFilesExists(docToImport, workingDir)) { ConfluenceUtils.handlePageTitleUniqueness(docToImport, titlePrefixBase, getSpace().getKey(), new ConfluenceUtils.PageManagerWrapper() { @Override public boolean pageExists(String spaceKey, String title) { return pageManager.getPage(spaceKey, title) != null; } }); importer.normalizeAllDocBookXMLFilesContent(workingDir); Page importRootPage = getPage(); Page importRootPageOrig = (Page) importRootPage.clone(); Page documentRootPage = importDocumentRoot(docToImport, importRootPage); importSubpages(docBookFileToImport, docToImport, documentRootPage, workingDir, docbookVersion); pageManager.saveContentEntity(documentRootPage, null); pageManager.saveContentEntity(importRootPage, importRootPageOrig, null); addActionMessage("Imported successfuly."); return "success"; } } } catch (Exception e) { logger.error("Error during DocBook file import: " + e.getMessage(), e); addActionError("Error during DocBook file import: " + e.getMessage()); } finally { if (!logger.isDebugEnabled()) { FileUtils.deleteDirectoryRecursively(workingDir); } } } } return "error"; } protected boolean validTitlePrefixBase() { if (titlePrefixBase == null) return true; if (titlePrefixBase.length() < 2 || titlePrefixBase.length() > 3) { addActionError("'Unique page title prefix base' must be two or three characters long"); return false; } else { for (char ch : titlePrefixBase.toCharArray()) { if (!Character.isLetterOrDigit(ch)) { addActionError("'Unique page title prefix base' must contain only letters or digits"); return false; } } } return true; } /** * Import document root into {@link Page}. Both returned object and <code>importRootPage</code> must be persisted * later using {@link PageManager}! * * @param docToImport info about document to read chapters from * @param importRootPage to add document root page as children to * @return {@link Page} object for document root */ private Page importDocumentRoot(DocStructureItem docToImport, Page importRootPage) { Page documentRootPage = preparePageObjectBase(docToImport, importRootPage); return documentRootPage; } /** * Prepare base for {@link Page} object. Title, Space and parent Page is set into returned object. Returned object is * added as child to parent object too. * <p> * Both returned object and <code>parentPage</code> must be persisted later using {@link PageManager}! * * @param pageStructureInfo info about page structure * @param parentPage parent page * @return prepared Page object */ private Page preparePageObjectBase(DocStructureItem pageStructureInfo, Page parentPage) { Page page = new Page(); page.setTitle(pageStructureInfo.getConfluencePageTitle()); page.setSpace(getSpace()); page.setParentPage(parentPage); parentPage.addChild(page); return page; } /** * Import childs of given DocStructureItem (chapters or sections) as subpages for given rootPage. * * @param docBookFileToImport DocBook xml <code>book</code> file used to import. * @param docToImport info about node to read childs from * @param rootPage root node page to add childs as subpages to * @param workDir to load referenced images from * @throws Exception */ private void importSubpages(File docBookFileToImport, DocStructureItem docToImport, Page rootPage, File workDir, DocBookVersion docbookVersion) throws Exception { int chapterPosition = 0; for (DocStructureItem chapterInfo : docToImport.getChilds()) { Page chapterPage = preparePageObjectBase(chapterInfo, rootPage); chapterPage.setPosition(chapterPosition++); chapterPage .setContent(importer.prepareNodeWIKIContent(docBookFileToImport, chapterInfo, docbookVersion)); importPageAttachments(chapterInfo, workDir, chapterPage); // import subpages recursively importSubpages(docBookFileToImport, chapterInfo, chapterPage, workDir, docbookVersion); pageManager.saveContentEntity(chapterPage, null); } } /** * Import attachments for Page. * * @param chapterInfo to import attachments for * @param workDir to read attachments from * @param chapterPage to add attachments to * @throws Exception */ private void importPageAttachments(DocStructureItem chapterInfo, File workDir, Page chapterPage) throws Exception { List<String> localRefs = chapterInfo.getFilerefsLocal(); if (localRefs != null && !localRefs.isEmpty()) { AttachmentManager attachmentManager = pageManager.getAttachmentManager(); Set<String> uniqueName = new HashSet<String>(); for (String ref : localRefs) { if (!uniqueName.contains(ref)) { uniqueName.add(ref); File af = new File(workDir, ref); Attachment attachment = new Attachment(); attachment.setFileName(importer.getFilenameFromFilerefLocal(ref)); attachment.setFileSize(af.length()); attachment.setContent(chapterPage); attachment.setContentType(mtftm.getContentType(af)); InputStream is = new FileInputStream(af); try { attachmentManager.saveAttachment(attachment, null, is); } finally { if (is != null) { is.close(); } } chapterPage.addAttachment(attachment); } } } } private boolean validateReferencedLocalFilesExists(DocStructureItem docToImport, File directory) { List<String> messages = new ArrayList<String>(); importer.validateImageFilesExists(docToImport, directory, messages); if (messages.isEmpty()) { return true; } else { for (String msg : messages) { addActionError(msg); } return false; } } }