Java tutorial
/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * 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.xwiki.wikistream.confluence.xml.internal.input; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.StringReader; import java.text.ParseException; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.slf4j.Logger; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.InstantiationStrategy; import org.xwiki.component.descriptor.ComponentInstantiationStrategy; import org.xwiki.filter.FilterEventParameters; import org.xwiki.rendering.listener.Listener; import org.xwiki.rendering.parser.StreamParser; import org.xwiki.rendering.syntax.Syntax; import org.xwiki.wikistream.WikiStreamException; import org.xwiki.wikistream.confluence.input.ConfluenceInputProperties; import org.xwiki.wikistream.confluence.xml.internal.ConfluenceFilter; import org.xwiki.wikistream.confluence.xml.internal.ConfluenceXMLPackage; import org.xwiki.wikistream.filter.user.GroupFilter; import org.xwiki.wikistream.filter.user.UserFilter; import org.xwiki.wikistream.internal.input.AbstractBeanInputWikiStream; import org.xwiki.wikistream.model.filter.WikiAttachmentFilter; import org.xwiki.wikistream.model.filter.WikiDocumentFilter; /** * @version $Id: 85e61d5df2225a5a32129802cd33a7efca6d38ec $ * @since 5.3M2 */ @Component @Named(ConfluenceInputWikiStreamFactory.ROLEHINT) @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP) public class ConfluenceInputWikiStream extends AbstractBeanInputWikiStream<ConfluenceInputProperties, ConfluenceFilter> { @Inject private Logger logger; @Inject @Named("confluence/1.0") private StreamParser confluenceWIKIParser; @Inject @Named("confluence+xhtml/1.0") private StreamParser confluenceXHTMLParser; private ConfluenceXMLPackage confluencePackage; @Override public void close() throws IOException { this.properties.getSource().close(); } @Override protected void read(Object filter, ConfluenceFilter proxyFilter) throws WikiStreamException { // Prepare package try { this.confluencePackage = new ConfluenceXMLPackage(this.properties.getSource()); } catch (Exception e) { throw new WikiStreamException("Failed to read package", e); } // Generate users events for (int userInt : this.confluencePackage.getUsers()) { PropertiesConfiguration userProperties; try { userProperties = this.confluencePackage.getUserProperties(userInt); } catch (ConfigurationException e) { throw new WikiStreamException("Failed to get user properties", e); } String userId = userProperties.getString(ConfluenceXMLPackage.KEY_USER_NAME, String.valueOf(userInt)); if (this.properties.isConvertToXWiki() && userId.equals("admin")) { userId = "Admin"; } FilterEventParameters userParameters = new FilterEventParameters(); userParameters.put(UserFilter.PARAMETER_FIRSTNAME, userProperties.getString(ConfluenceXMLPackage.KEY_USER_FIRSTNAME)); userParameters.put(UserFilter.PARAMETER_LASTNAME, userProperties.getString(ConfluenceXMLPackage.KEY_USER_LASTNAME)); userParameters.put(UserFilter.PARAMETER_EMAIL, userProperties.getString(ConfluenceXMLPackage.KEY_USER_EMAIL)); userParameters.put(UserFilter.PARAMETER_ACTIVE, userProperties.getBoolean(ConfluenceXMLPackage.KEY_USER_ACTIVE)); try { userParameters.put(UserFilter.PARAMETER_REVISION_DATE, this.confluencePackage .getDate(userProperties, ConfluenceXMLPackage.KEY_USER_REVISION_DATE)); userParameters.put(UserFilter.PARAMETER_CREATION_DATE, this.confluencePackage .getDate(userProperties, ConfluenceXMLPackage.KEY_USER_CREATION_DATE)); } catch (ParseException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse date", e); } } // TODO: no idea how to import/convert the password, probably salted with the Confluence instance id // > User proxyFilter.beginUser(userId, userParameters); // < User proxyFilter.endUser(userId, userParameters); } // Generate users events for (int groupInt : this.confluencePackage.getGroups()) { PropertiesConfiguration groupProperties; try { groupProperties = this.confluencePackage.getGroupProperties(groupInt); } catch (ConfigurationException e) { throw new WikiStreamException("Failed to get group properties", e); } String groupId = groupProperties.getString(ConfluenceXMLPackage.KEY_GROUP_NAME, String.valueOf(groupInt)); if (this.properties.isConvertToXWiki()) { if (groupId.equals("confluence-administrators")) { groupId = "XWikiAdminGroup"; } else if (groupId.equals("confluence-users")) { groupId = "XWikiAllGroup"; } } FilterEventParameters groupParameters = new FilterEventParameters(); try { groupParameters.put(GroupFilter.PARAMETER_REVISION_DATE, this.confluencePackage .getDate(groupProperties, ConfluenceXMLPackage.KEY_GROUP_REVISION_DATE)); groupParameters.put(GroupFilter.PARAMETER_CREATION_DATE, this.confluencePackage .getDate(groupProperties, ConfluenceXMLPackage.KEY_GROUP_CREATION_DATE)); } catch (ParseException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse date", e); } } // > Group proxyFilter.beginGroup(groupId, groupParameters); // Members users if (groupProperties.containsKey(ConfluenceXMLPackage.KEY_GROUP_MEMBERUSERS)) { List<Integer> users = this.confluencePackage.getIntegertList(groupProperties, ConfluenceXMLPackage.KEY_GROUP_MEMBERUSERS); for (Integer memberInt : users) { FilterEventParameters memberParameters = new FilterEventParameters(); try { String memberId = this.confluencePackage.getUserProperties(memberInt) .getString(ConfluenceXMLPackage.KEY_USER_NAME, String.valueOf(memberInt)); if (this.properties.isConvertToXWiki() && memberId.equals("admin")) { memberId = "Admin"; } proxyFilter.onGroupMemberGroup(memberId, memberParameters); } catch (ConfigurationException e) { this.logger.error("Failed to get user properties", e); } } } // Members groups if (groupProperties.containsKey(ConfluenceXMLPackage.KEY_GROUP_MEMBERGROUPS)) { List<Integer> groups = this.confluencePackage.getIntegertList(groupProperties, ConfluenceXMLPackage.KEY_GROUP_MEMBERGROUPS); for (Integer memberInt : groups) { FilterEventParameters memberParameters = new FilterEventParameters(); try { String memberId = this.confluencePackage.getGroupProperties(memberInt) .getString(ConfluenceXMLPackage.KEY_GROUP_NAME, String.valueOf(memberInt)); if (this.properties.isConvertToXWiki()) { if (memberId.equals("confluence-administrators")) { memberId = "XWikiAdminGroup"; } else if (memberId.equals("confluence-users")) { memberId = "XWikiAllGroup"; } } proxyFilter.onGroupMemberGroup(memberId, memberParameters); } catch (ConfigurationException e) { this.logger.error("Failed to get group properties", e); } } } // < Group proxyFilter.endGroup(groupId, groupParameters); } // Generate documents events for (Map.Entry<Integer, List<Integer>> entry : this.confluencePackage.getPages().entrySet()) { int spaceId = entry.getKey(); PropertiesConfiguration spaceProperties; try { spaceProperties = this.confluencePackage.getSpaceProperties(spaceId); } catch (ConfigurationException e) { throw new WikiStreamException("Failed to get space properties", e); } String spaceName = spaceProperties.getString(ConfluenceXMLPackage.KEY_SPACE_NAME); FilterEventParameters spaceParameters = new FilterEventParameters(); // > WikiSpace proxyFilter.beginWikiSpace(spaceName, spaceParameters); // Main page if (spaceProperties.containsKey(ConfluenceXMLPackage.KEY_SPACE_DESCRIPTION)) { readPage(spaceProperties.getInt(ConfluenceXMLPackage.KEY_SPACE_DESCRIPTION), filter, proxyFilter); } // Other pages for (int pageId : entry.getValue()) { readPage(pageId, filter, proxyFilter); } // < WikiSpace proxyFilter.endWikiSpace(spaceName, spaceParameters); } // Cleanup try { this.confluencePackage.close(); } catch (IOException e) { throw new WikiStreamException("Failed to close package", e); } } private void readPage(int pageId, Object filter, ConfluenceFilter proxyFilter) throws WikiStreamException { PropertiesConfiguration pageProperties = getPageProperties(pageId); String documentName; if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_HOMEPAGE)) { documentName = this.properties.getSpacePageName(); } else { documentName = pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_TITLE); } FilterEventParameters documentParameters = new FilterEventParameters(); if (this.properties.getDefaultLocale() != null) { documentParameters.put(WikiDocumentFilter.PARAMETER_LOCALE, this.properties.getDefaultLocale()); } // > WikiDocument proxyFilter.beginWikiDocument(documentName, documentParameters); Locale locale = Locale.ROOT; FilterEventParameters documentLocaleParameters = new FilterEventParameters(); if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_CREATION_AUTHOR)) { documentLocaleParameters.put(WikiDocumentFilter.PARAMETER_CREATION_AUTHOR, pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_CREATION_AUTHOR)); } if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_CREATION_DATE)) { try { documentLocaleParameters.put(WikiDocumentFilter.PARAMETER_CREATION_DATE, this.confluencePackage .getDate(pageProperties, ConfluenceXMLPackage.KEY_PAGE_CREATION_DATE)); } catch (ParseException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse date", e); } } } if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_REVISION)) { documentLocaleParameters.put(WikiDocumentFilter.PARAMETER_LASTREVISION, pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_REVISION)); } // > WikiDocumentLocale proxyFilter.beginWikiDocumentLocale(locale, documentLocaleParameters); // Revisions if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_REVISIONS)) { List<Integer> revisions = this.confluencePackage.getIntegertList(pageProperties, ConfluenceXMLPackage.KEY_PAGE_REVISIONS); for (Integer revisionId : revisions) { readPageRevision(revisionId, filter, proxyFilter); } } // Current version readPageRevision(pageId, filter, proxyFilter); // < WikiDocumentLocale proxyFilter.endWikiDocumentLocale(locale, documentLocaleParameters); // < WikiDocument proxyFilter.endWikiDocument(documentName, documentParameters); } private PropertiesConfiguration getPageProperties(Integer pageId) throws WikiStreamException { try { return this.confluencePackage.getPageProperties(pageId); } catch (ConfigurationException e) { throw new WikiStreamException("Failed to get page properties", e); } } private void readPageRevision(Integer pageId, Object filter, ConfluenceFilter proxyFilter) throws WikiStreamException { PropertiesConfiguration pageProperties = getPageProperties(pageId); readPageRevision(pageId, pageProperties, filter, proxyFilter); } private void readPageRevision(int pageId, PropertiesConfiguration pageProperties, Object filter, ConfluenceFilter proxyFilter) throws WikiStreamException { String revision = pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_REVISION); FilterEventParameters documentRevisionParameters = new FilterEventParameters(); if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_PARENT)) { try { documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_PARENT, this.confluencePackage .getReferenceFromId(pageProperties, ConfluenceXMLPackage.KEY_PAGE_PARENT)); } catch (ConfigurationException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse parent", e); } } } if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_REVISION_AUTHOR)) { documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_REVISION_AUTHOR, pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_REVISION_AUTHOR)); } if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_REVISION_DATE)) { try { documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_REVISION_DATE, this.confluencePackage .getDate(pageProperties, ConfluenceXMLPackage.KEY_PAGE_REVISION_DATE)); } catch (ParseException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse date", e); } } } if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_REVISION_COMMENT)) { documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_REVISION_COMMENT, pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_REVISION_COMMENT)); } documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_TITLE, pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_TITLE)); String bodyContent = null; Syntax bodySyntax = null; int bodyType = -1; if (pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_BODY) && pageProperties.containsKey(ConfluenceXMLPackage.KEY_PAGE_BODY_TYPE)) { bodyContent = pageProperties.getString(ConfluenceXMLPackage.KEY_PAGE_BODY); bodyType = pageProperties.getInt(ConfluenceXMLPackage.KEY_PAGE_BODY_TYPE); switch (bodyType) { case 0: bodySyntax = Syntax.CONFLUENCE_1_0; break; case 2: bodySyntax = Syntax.CONFLUENCEXHTML_1_0; break; default: if (this.properties.isVerbose()) { this.logger.error("Unknown body type [{}]", bodyType); } break; } } // If target filter does not support rendering events, pass the content as it is if (!(filter instanceof Listener) && bodyContent != null && bodySyntax != null) { documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_CONTENT, bodyContent); documentRevisionParameters.put(WikiDocumentFilter.PARAMETER_SYNTAX, bodySyntax); } // > WikiDocumentRevision proxyFilter.beginWikiDocumentRevision(revision, documentRevisionParameters); // Content if (filter instanceof Listener && bodyContent != null && bodySyntax != null) { try { switch (bodyType) { case 0: this.confluenceWIKIParser.parse(new StringReader(bodyContent), proxyFilter); break; case 2: this.confluenceXHTMLParser.parse(new StringReader(bodyContent), proxyFilter); break; default: break; } } catch (org.xwiki.rendering.parser.ParseException e) { throw new WikiStreamException(String.format("Failed parser content [%s]", bodyContent), e); } } // Attachments Map<String, PropertiesConfiguration> pageAttachments = new LinkedHashMap<String, PropertiesConfiguration>(); for (int attachmentId : this.confluencePackage.getAttachments(pageId)) { PropertiesConfiguration attachmentProperties; try { attachmentProperties = this.confluencePackage.getAttachmentProperties(pageId, attachmentId); } catch (ConfigurationException e) { throw new WikiStreamException("Failed to get attachment properties", e); } String attachmentName = attachmentProperties.getString(ConfluenceXMLPackage.KEY_ATTACHMENT_NAME); PropertiesConfiguration currentAttachmentProperties = pageAttachments.get(attachmentName); if (currentAttachmentProperties != null) { int version = attachmentProperties.getInt(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION); int currentVersion = currentAttachmentProperties .getInt(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION); if (version > currentVersion) { pageAttachments.put(attachmentName, attachmentProperties); } } else { pageAttachments.put(attachmentName, attachmentProperties); } } for (PropertiesConfiguration attachmentProperties : pageAttachments.values()) { readAttachment(pageId, attachmentProperties, filter, proxyFilter); } // < WikiDocumentRevision proxyFilter.endWikiDocumentRevision(revision, documentRevisionParameters); } private void readAttachment(int pageId, PropertiesConfiguration attachmentProperties, Object filter, ConfluenceFilter proxyFilter) throws WikiStreamException { int attachmentId = attachmentProperties.getInt("id"); String attachmentName = attachmentProperties.getString(ConfluenceXMLPackage.KEY_ATTACHMENT_NAME); long attachmentSize = attachmentProperties.getLong(ConfluenceXMLPackage.KEY_ATTACHMENT_CONTENT_SIZE); int version = attachmentProperties.getInt(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION); int originalRevisionId = attachmentProperties.getInt(ConfluenceXMLPackage.KEY_ATTACHMENT_ORIGINAL_REVISION, attachmentId); File contentFile = this.confluencePackage.getAttachmentFile(pageId, originalRevisionId, version); FilterEventParameters attachmentParameters = new FilterEventParameters(); if (attachmentProperties.containsKey(ConfluenceXMLPackage.KEY_ATTACHMENT_CONTENT_TYPE)) { attachmentParameters.put(WikiAttachmentFilter.PARAMETER_CONTENT_TYPE, attachmentProperties.getString(ConfluenceXMLPackage.KEY_ATTACHMENT_CONTENT_TYPE)); } if (attachmentProperties.containsKey(ConfluenceXMLPackage.KEY_ATTACHMENT_CREATION_AUTHOR)) { attachmentParameters.put(WikiAttachmentFilter.PARAMETER_CREATION_AUTHOR, attachmentProperties.getString(ConfluenceXMLPackage.KEY_ATTACHMENT_CREATION_AUTHOR)); } if (attachmentProperties.containsKey(ConfluenceXMLPackage.KEY_ATTACHMENT_CREATION_DATE)) { try { attachmentParameters.put(WikiAttachmentFilter.PARAMETER_CREATION_DATE, this.confluencePackage .getDate(attachmentProperties, ConfluenceXMLPackage.KEY_ATTACHMENT_CREATION_DATE)); } catch (ParseException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse date", e); } } } attachmentParameters.put(WikiAttachmentFilter.PARAMETER_REVISION, String.valueOf(version)); if (attachmentProperties.containsKey(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION_AUTHOR)) { attachmentParameters.put(WikiAttachmentFilter.PARAMETER_REVISION_AUTHOR, attachmentProperties.getString(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION_AUTHOR)); } if (attachmentProperties.containsKey(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION_DATE)) { try { attachmentParameters.put(WikiAttachmentFilter.PARAMETER_REVISION_DATE, this.confluencePackage .getDate(attachmentProperties, ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION_DATE)); } catch (ParseException e) { if (this.properties.isVerbose()) { this.logger.error("Failed to parse date", e); } } } if (attachmentProperties.containsKey(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION_COMMENT)) { attachmentParameters.put(WikiAttachmentFilter.PARAMETER_REVISION_COMMENT, attachmentProperties.getString(ConfluenceXMLPackage.KEY_ATTACHMENT_REVISION_COMMENT)); } // WikiAttachment try { FileInputStream fis = new FileInputStream(contentFile); try { proxyFilter.onWikiAttachment(attachmentName, fis, attachmentSize, attachmentParameters); } finally { fis.close(); } } catch (Exception e) { throw new WikiStreamException("Failed to read attachment", e); } } }