/*
* 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.filter.xar.internal.input;
import java.io.IOException;
import java.io.InputStream;
import javax.inject.Inject;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.lang3.exception.ExceptionUtils;
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.filter.FilterException;
import org.xwiki.filter.event.model.WikiDocumentFilter;
import org.xwiki.filter.input.InputSource;
import org.xwiki.filter.input.InputStreamInputSource;
import org.xwiki.filter.xar.input.XARInputProperties;
import org.xwiki.logging.marker.TranslationMarker;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.xar.XarPackage;
import org.xwiki.xar.internal.model.XarModel;
/**
* @version $Id: c3b8bf4c97c0938409fc4acf2772f8342500ef68 $
* @since 6.2M1
*/
@Component(roles = WikiReader.class)
@InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
public class WikiReader
{
private static final TranslationMarker LOG_DOCUMENT_SKIPPED = new TranslationMarker(
"filter.xar.log.document.skipped", WikiDocumentFilter.LOG_DOCUMENT_SKIPPED);
private static final TranslationMarker LOG_DOCUMENT_FAILREAD = new TranslationMarker(
"filter.xar.log.document.failread", WikiDocumentFilter.LOG_DOCUMENT_ERROR);
private static final TranslationMarker LOG_DESCRIPTOR_FAILREAD = new TranslationMarker(
"filter.xar.log.descriptor.failread");
@Inject
private DocumentLocaleReader documentReader;
@Inject
private Logger logger;
private XARInputProperties properties;
private XarPackage xarPackage = new XarPackage();
public void setProperties(XARInputProperties properties)
{
this.properties = properties;
this.documentReader.setProperties(properties);
}
public XarPackage getXarPackage()
{
return this.xarPackage;
}
public void read(Object filter, XARInputFilter proxyFilter) throws IOException, FilterException
{
InputStream stream;
InputSource source = this.properties.getSource();
if (source instanceof InputStreamInputSource) {
stream = ((InputStreamInputSource) source).getInputStream();
} else {
throw new FilterException("Unsupported source type [" + source.getClass() + "]");
}
read(stream, filter, proxyFilter);
// Close remaining opened spaces
if (this.documentReader.getSentSpaceReference() != null) {
for (EntityReference space = this.documentReader.getSentSpaceReference(); space != null; space =
space.getParent()) {
proxyFilter.endWikiSpace(space.getName(), FilterEventParameters.EMPTY);
}
}
// Send extension event
if (this.xarPackage.getPackageExtensionId() != null) {
proxyFilter.beginExtension(this.xarPackage.getPackageExtensionId(), this.xarPackage.getPackageVersion(),
FilterEventParameters.EMPTY);
proxyFilter.endExtension(this.xarPackage.getPackageExtensionId(), this.xarPackage.getPackageVersion(),
FilterEventParameters.EMPTY);
}
}
public void read(InputStream stream, Object filter, XARInputFilter proxyFilter) throws IOException
{
ZipArchiveInputStream zis = new ZipArchiveInputStream(stream, "UTF-8", false);
for (ZipArchiveEntry entry = zis.getNextZipEntry(); entry != null; entry = zis.getNextZipEntry()) {
if (entry.isDirectory() || entry.getName().startsWith("META-INF")) {
// The entry is either a directory or is something inside of the META-INF dir.
// (we use that directory to put meta data such as LICENSE/NOTICE files.)
continue;
} else if (entry.getName().equals(XarModel.PATH_PACKAGE)) {
// The entry is the manifest (package.xml). Read this differently.
try {
this.xarPackage.readDescriptor(zis);
} catch (Exception e) {
if (this.properties.isVerbose()) {
this.logger.warn(LOG_DESCRIPTOR_FAILREAD, "Failed to read XAR descriptor from entry [{}]: {}",
entry.getName(), ExceptionUtils.getRootCauseMessage(e));
}
}
} else {
try {
this.documentReader.read(zis, filter, proxyFilter);
} catch (SkipEntityException skip) {
if (this.properties.isVerbose()) {
this.logger.info(LOG_DOCUMENT_SKIPPED, "Skipped document [{}]", skip.getEntityReference());
}
} catch (Exception e) {
if (this.properties.isVerbose()) {
this.logger.warn(LOG_DOCUMENT_FAILREAD, "Failed to read XAR XML document from entry [{}]: {}",
entry.getName(), ExceptionUtils.getRootCauseMessage(e), e);
}
}
}
}
}
}