/* * 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.instance.internal.input; import java.io.IOException; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; 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.component.manager.ComponentLookupException; import org.xwiki.component.manager.ComponentManager; import org.xwiki.filter.FilterEventParameters; import org.xwiki.filter.FilterException; import org.xwiki.filter.event.model.WikiDocumentFilter; import org.xwiki.filter.input.AbstractBeanInputFilterStream; import org.xwiki.filter.instance.input.InstanceInputEventGenerator; import org.xwiki.filter.instance.input.InstanceInputProperties; import org.xwiki.filter.instance.internal.InstanceFilter; import org.xwiki.filter.instance.internal.InstanceModel; import org.xwiki.filter.instance.internal.InstanceUtils; import org.xwiki.logging.marker.TranslationMarker; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.EntityReferenceTreeNode; import org.xwiki.model.reference.SpaceReference; import org.xwiki.model.reference.WikiReference; /** * @version $Id: 7cf545d63d8faadb0a1166242aa2a064dac09702 $ * @since 6.2M1 */ @Component @Named(InstanceUtils.ROLEHINT) @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP) public class InstanceInputFilterStream extends AbstractBeanInputFilterStream<InstanceInputProperties, InstanceFilter> { private static final TranslationMarker LOG_DOCUMENT_SKIPPED = new TranslationMarker( "filter.instance.log.document.skipped", WikiDocumentFilter.LOG_DOCUMENT_SKIPPED); @Inject private InstanceModel instanceModel; @Inject @Named("context") private Provider<ComponentManager> componentManager; @Inject private Logger logger; private List<InstanceInputEventGenerator> eventGenerators; @Override public void setProperties(InstanceInputProperties properties) throws FilterException { super.setProperties(properties); try { this.eventGenerators = this.componentManager.get().getInstanceList(InstanceInputEventGenerator.class); } catch (ComponentLookupException e) { throw new FilterException( "Failed to get regsitered instance of OutputInstanceFilterStreamFactory components", e); } for (InstanceInputEventGenerator eventGenerator : this.eventGenerators) { eventGenerator.setProperties(this.properties); } } private boolean isWikiEnabled(WikiReference wikiReference) { return this.properties.getEntities() == null || this.properties.getEntities().matches(wikiReference); } private boolean isSpaceEnabled(SpaceReference spaceReference) { return this.properties.getEntities() == null || this.properties.getEntities().matches(spaceReference); } private boolean isDocumentEnabled(DocumentReference documentReference) { return this.properties.getEntities() == null || this.properties.getEntities().matches(documentReference); } @Override public void close() throws IOException { // Nothing do close } @Override protected void read(Object filter, InstanceFilter proxyFilter) throws FilterException { FilterEventParameters parameters = new FilterEventParameters(); for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.setWikiFarmParameters(parameters); } proxyFilter.beginWikiFarm(parameters); for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.setFilter(filter); generator.beginWikiFarm(parameters); } for (WikiReference wikiReference : this.instanceModel.getWikiReferences()) { if (isWikiEnabled(wikiReference)) { writeWiki(wikiReference, filter, proxyFilter); } } for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.endWikiFarm(parameters); } proxyFilter.endWikiFarm(parameters); } private void writeWiki(WikiReference wikiReference, Object filter, InstanceFilter proxyFilter) throws FilterException { FilterEventParameters parameters = new FilterEventParameters(); for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.setWikiParameters(wikiReference.getName(), parameters); } proxyFilter.beginWiki(wikiReference.getName(), parameters); for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.beginWiki(wikiReference.getName(), parameters); } // TODO: improve with a new space related API to get space level by space level instead of all of them at the // same time EntityReferenceTreeNode spaces = this.instanceModel.getSpaceReferences(wikiReference); for (EntityReferenceTreeNode node : spaces.getChildren()) { if (isSpaceEnabled((SpaceReference) node.getReference())) { writeSpace(node, filter, proxyFilter); } } for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.endWiki(wikiReference.getName(), parameters); } proxyFilter.endWiki(wikiReference.getName(), parameters); } private void writeSpace(EntityReferenceTreeNode node, Object filter, InstanceFilter proxyFilter) throws FilterException { SpaceReference spaceReference = (SpaceReference) node.getReference(); FilterEventParameters parameters = new FilterEventParameters(); // Get begin/end space parameters for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.setWikiSpaceParameters(spaceReference.getName(), parameters); } // Begin space proxyFilter.beginWikiSpace(spaceReference.getName(), parameters); // Extend begin space for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.beginWikiSpace(spaceReference.getName(), parameters); } // Write documents for (DocumentReference documentReference : this.instanceModel.getDocumentReferences(spaceReference)) { if (isDocumentEnabled(documentReference)) { writeDocument(documentReference, filter, proxyFilter); } else { if (this.properties.isVerbose()) { this.logger.info(LOG_DOCUMENT_SKIPPED, "Skipped document [{}]", documentReference); } } } // Write nested spaces for (EntityReferenceTreeNode child : node.getChildren()) { writeSpace(child, filter, proxyFilter); } // Extend end space for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.endWikiSpace(spaceReference.getName(), parameters); } // End space proxyFilter.endWikiSpace(spaceReference.getName(), parameters); } private void writeDocument(DocumentReference documentReference, Object filter, InstanceFilter proxyFilter) throws FilterException { FilterEventParameters parameters = new FilterEventParameters(); for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.setWikiDocumentParameters(documentReference.getName(), parameters); } proxyFilter.beginWikiDocument(documentReference.getName(), parameters); for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.beginWikiDocument(documentReference.getName(), parameters); } for (InstanceInputEventGenerator generator : this.eventGenerators) { generator.endWikiDocument(documentReference.getName(), parameters); } proxyFilter.endWikiDocument(documentReference.getName(), parameters); } }