/* * 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 com.xpn.xwiki.internal.filter.output; import javax.inject.Inject; import javax.inject.Provider; import org.apache.commons.lang3.StringUtils; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.InstantiationStrategy; import org.xwiki.component.descriptor.ComponentInstantiationStrategy; import org.xwiki.component.phase.Initializable; import org.xwiki.component.phase.InitializationException; import org.xwiki.filter.FilterEventParameters; import org.xwiki.filter.FilterException; import org.xwiki.filter.event.model.WikiObjectFilter; import org.xwiki.model.reference.EntityReference; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.objects.BaseObject; import com.xpn.xwiki.objects.BaseObjectReference; import com.xpn.xwiki.objects.BaseProperty; import com.xpn.xwiki.objects.classes.BaseClass; /** * @version $Id: db0b372693ec29fef872010c79adc9557b9e6617 $ * @since 9.0RC1 */ @Component @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP) public class BaseObjectOutputFilterStream extends AbstractEntityOutputFilterStream<BaseObject> implements Initializable { @Inject private EntityOutputFilterStream<BaseClass> classFilter; @Inject private EntityOutputFilterStream<BaseProperty> propertyFilter; @Inject private Provider<XWikiContext> xcontextProvider; private BaseObject externalEntity; @Override public void initialize() throws InitializationException { initialize(this.classFilter, this.propertyFilter); } @Override public void setEntity(BaseObject entity) { super.setEntity(entity); this.externalEntity = entity; } private BaseClassOutputFilterStream getBaseClassOutputFilterStream() { return (BaseClassOutputFilterStream) this.classFilter; } private BasePropertyOutputFilterStream getBasePropertyOutputFilterStream() { return (BasePropertyOutputFilterStream) this.propertyFilter; } private void setCurrentXClass(BaseClass xclass) { getBasePropertyOutputFilterStream().setCurrentXClass(xclass); } // Events @Override public void endWikiClass(FilterEventParameters parameters) throws FilterException { if (this.entity != null) { BaseClass xclass = getBaseClassOutputFilterStream().getEntity(); if (xclass != null) { // Re-create the object instance if not already provided and if there is a custom class if (this.externalEntity == null && StringUtils.isNotEmpty(xclass.getCustomClass())) { BaseObject customObject; try { customObject = xclass.newCustomClassInstance(this.xcontextProvider.get()); customObject.setDocumentReference(this.entity.getDocumentReference()); customObject.setXClassReference(this.entity.getXClassReference()); customObject.setOwnerDocument(this.entity.getOwnerDocument()); // Pass false as an optimization since there is nothing to clean on a new object customObject.apply(this.entity, false); this.entity = customObject; } catch (XWikiException e) { // TODO: should probably log a warning } } setCurrentXClass(xclass); getBaseClassOutputFilterStream().setEntity(null); } } } @Override public void beginWikiObject(String name, FilterEventParameters parameters) throws FilterException { super.beginWikiObject(name, parameters); if (this.enabled) { if (this.entity == null) { this.entity = new BaseObject(); } if (parameters.containsKey(WikiObjectFilter.PARAMETER_NAME)) { this.entity .setDocumentReference(getDocumentReference(WikiObjectFilter.PARAMETER_NAME, parameters, null)); } int number = getInt(WikiObjectFilter.PARAMETER_NUMBER, parameters, -1); EntityReference classReference = getEntityReference(WikiObjectFilter.PARAMETER_CLASS_REFERENCE, parameters, null); if (classReference == null) { BaseObjectReference reference = new BaseObjectReference(this.currentEntityReference); classReference = reference.getXClassReference(); if (number < 0 && reference.getObjectNumber() != null) { number = reference.getObjectNumber(); } } this.entity.setXClassReference(classReference); // Get the class in the current instance XWikiContext xcontext = this.xcontextProvider.get(); if (xcontext != null && xcontext.getWiki() != null) { try { setCurrentXClass(xcontext.getWiki().getXClass(this.entity.getXClassReference(), xcontext)); } catch (XWikiException e) { // TODO: log something ? } } this.entity.setNumber(number); this.entity.setGuid(getString(WikiObjectFilter.PARAMETER_GUID, parameters, null)); getBaseClassOutputFilterStream().enable(); getBasePropertyOutputFilterStream().enable(); } } @Override public void endWikiObject(String name, FilterEventParameters parameters) throws FilterException { super.endWikiObject(name, parameters); getBaseClassOutputFilterStream().disable(); getBaseClassOutputFilterStream().disable(); } @Override public void onWikiObjectProperty(String name, Object value, FilterEventParameters parameters) throws FilterException { if (this.enabled) { if (getBasePropertyOutputFilterStream().getEntity() != null) { this.entity.safeput(name, getBasePropertyOutputFilterStream().getEntity()); getBasePropertyOutputFilterStream().setEntity(null); } } } }