/* * JBoss, Home of Professional Open Source * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.jboss.as.console.mbui.reification; import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.core.client.Scheduler; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Widget; import com.google.web.bindery.event.shared.EventBus; import org.jboss.as.console.client.shared.properties.ModelNodePropertyEditor; import org.jboss.as.console.client.shared.properties.ModelNodePropertyManagement; import org.jboss.as.console.mbui.JBossQNames; import org.jboss.as.console.mbui.model.StereoTypes; import org.jboss.as.console.mbui.model.mapping.DMRMapping; import org.jboss.ballroom.client.rbac.SecurityContext; import org.jboss.dmr.client.ModelNode; import org.jboss.dmr.client.Property; import org.useware.kernel.gui.behaviour.InteractionEvent; import org.useware.kernel.gui.behaviour.PresentationEvent; import org.useware.kernel.gui.behaviour.SystemEvent; import org.useware.kernel.gui.behaviour.common.CommonQNames; import org.useware.kernel.gui.reification.Context; import org.useware.kernel.gui.reification.ContextKey; import org.useware.kernel.gui.reification.strategy.ReificationStrategy; import org.useware.kernel.gui.reification.strategy.ReificationWidget; import org.useware.kernel.model.behaviour.Resource; import org.useware.kernel.model.behaviour.ResourceType; import org.useware.kernel.model.mapping.MappingType; import org.useware.kernel.model.mapping.Predicate; import org.useware.kernel.model.structure.InteractionUnit; import org.useware.kernel.model.structure.QName; import java.util.List; import java.util.Map; import static org.useware.kernel.gui.behaviour.common.CommonQNames.RESET_ID; import static org.useware.kernel.model.behaviour.ResourceType.*; import static org.useware.kernel.model.behaviour.ResourceType.System; /** * @author Harald Pehl * @author Heiko Braun * @date 11/01/2012 */ public class PropertiesStrategy implements ReificationStrategy<ReificationWidget, StereoTypes> { private ModelNode modelDescription; private EventBus eventBus; private static final Resource<ResourceType> SAVE_EVENT = new Resource<ResourceType>(JBossQNames.SAVE_ID, Interaction); private static final Resource<ResourceType> LOAD_EVENT = new Resource<ResourceType>(JBossQNames.LOAD_ID, Interaction); private static final Resource<ResourceType> RESET = new Resource<ResourceType>(RESET_ID, System); private SecurityContext securityContext; @Override public boolean prepare(InteractionUnit<StereoTypes> interactionUnit, Context context) { Map<QName, ModelNode> descriptions = context.get (ContextKey.MODEL_DESCRIPTIONS); // TODO (BUG): After the first reification the behaviour is modified, // so the predicate might apply to a different unit. As a result the correlation id is different! QName correlationId = interactionUnit.findMapping(MappingType.DMR, new Predicate<DMRMapping>() { @Override public boolean appliesTo(DMRMapping candidate) { return candidate.getAddress()!=null; } }).getCorrelationId(); modelDescription = descriptions.get(correlationId); eventBus = context.get(ContextKey.EVENTBUS); securityContext = context.get(ContextKey.SECURITY_CONTEXT); return eventBus!=null && modelDescription!=null && securityContext!=null; } @Override public ReificationWidget reify(final InteractionUnit<StereoTypes> interactionUnit, final Context context) { return new PropertyEditorAdapter(interactionUnit, eventBus, modelDescription); } @Override public boolean appliesTo(final InteractionUnit<StereoTypes> interactionUnit) { return StereoTypes.Properties == interactionUnit.getStereotype(); } class PropertyEditorAdapter implements ReificationWidget, ModelNodePropertyManagement { final InteractionUnit interactionUnit; private final ModelNodePropertyEditor editor; private String objectName = null; private SafeHtmlBuilder helpTexts; private EventBus coordinator; PropertyEditorAdapter(final InteractionUnit<StereoTypes> interactionUnit, EventBus coordinator, final ModelNode modelDescription) { this.interactionUnit = interactionUnit; this.coordinator = coordinator; DMRMapping dmrMapping = (DMRMapping) this.interactionUnit.findMapping(MappingType.DMR); ModelNode attDesc = modelDescription.get("attributes").asObject(); if(dmrMapping.getObjects().size()>0 && attDesc .hasDefined(dmrMapping.getObjects().get(0))) { // mapped to ModelType.Object objectName = dmrMapping.getObjects().get(0); ModelNode description = attDesc.get(objectName).asObject(); Log.debug(description.toString()); } else { Log.warn(interactionUnit.getId() + "is missing valid DMR mapping"); } this.editor = new ModelNodePropertyEditor(PropertyEditorAdapter.this, true); } @Override public void onCreateProperty(String reference, Property prop) { } @Override public void onDeleteProperty(String reference, Property prop) { Window.alert("Not yet implemented"); } @Override public void onChangeProperty(String reference, Property prop) { } @Override public void launchNewPropertyDialoge(String reference) { Window.alert("Not yet implemented"); } @Override public void closePropertyDialoge() { } @Override public InteractionUnit getInteractionUnit() { return interactionUnit; } @Override public void add(final ReificationWidget widget) { throw new UnsupportedOperationException(); } @Override public Widget asWidget() { // handle resets within this scope coordinator.addHandler(SystemEvent.TYPE, new SystemEvent.Handler() { @Override public boolean accepts(SystemEvent event) { return event.getId().equals(CommonQNames.RESET_ID) ; } @Override public void onSystemEvent(SystemEvent event) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { // request loading of data InteractionEvent loadEvent = new InteractionEvent(JBossQNames.LOAD_ID); // update interaction units coordinator.fireEventFromSource( loadEvent, interactionUnit.getId() ); } }); } }); // handle the results of function calls coordinator.addHandler(PresentationEvent.TYPE, new PresentationEvent.PresentationHandler() { @Override public boolean accepts(PresentationEvent event) { boolean matchingId = event.getTarget().equals(getInteractionUnit().getId()); // only single resources accepted (might be collection, see LoadResourceProcedure) boolean payloadMatches = event.getPayload() instanceof ModelNode; return matchingId && payloadMatches; } @Override public void onPresentationEvent(PresentationEvent event) { assert (event.getPayload() instanceof ModelNode) : "Unexpected type "+event.getPayload().getClass(); ModelNode modelNode = (ModelNode)event.getPayload(); if(modelNode.hasDefined(objectName)) { List<Property> properties = modelNode.get(objectName).asPropertyList(); editor.setProperties("self", properties); } } }); // Register inputs and outputs Resource<ResourceType> update = new Resource<ResourceType>(getInteractionUnit().getId(), Presentation); getInteractionUnit().setOutputs(SAVE_EVENT, LOAD_EVENT); getInteractionUnit().setInputs(RESET, update); return editor.asWidget(); } } }