package org.richfaces.cdk.model; /** * That class represents JSF component in the CDK. That is mapped to faces-config "component" element. * * @author asmirnov@exadel.com * */ public final class ComponentModel extends ModelElementBase implements ModelElement<ComponentModel>, Cacheable { private static final long serialVersionUID = 2297349356280370771L; /** * <p class="changed_added_4_0"> * Facets recognised by the component * </p> */ private final ModelCollection<FacetModel> facets = ModelSet.<FacetModel>create(); /** * <p class="changed_added_4_0"> * Application level events fired by the component * </p> */ private final ModelCollection<EventModel> events = ModelSet.<EventModel>create(); /** * <p class="changed_added_4_0"> * JsfRenderer for the final component. This is bidirectional many to many relation. * </p> */ private FacesId family; private FacesId rendererType; private String rendererTemplate; private ComponentModel parent; private boolean changed = true; private boolean changeTracking = true; public ComponentModel(FacesId key) { this.setId(key); } public ComponentModel() { } public <R, D> R accept(Visitor<R, D> visitor, D data) { return visitor.visitComponent(this, data); // TODO ??? see at render kit // for (RendererModel rendererType : renderers) { // rendererType.accept(visitor); // } } @Override public void merge(ComponentModel otherComponent) { if (this.changeTracking) { this.changed = true; } // merge facets, renderers, events ... ComponentLibrary.merge(getAttributes(), otherComponent.getAttributes()); ComponentLibrary.merge(getFacets(), otherComponent.getFacets()); ComponentLibrary.merge(getEvents(), otherComponent.getEvents()); ComponentLibrary.merge(this, otherComponent); } @Override public boolean same(ComponentModel other) { if (null != getId() && null != other.getId()) { // Both types not null, compare them. return getId().equals(other.getId()); } // one or both types are null, compare classes. return null != getTargetClass() && getTargetClass().equals(other.getTargetClass()); } /** * <p class="changed_added_4_0"> * </p> * * @return the rendererType */ @Merge public FacesId getRendererType() { return this.rendererType; } /** * <p class="changed_added_4_0"> * </p> * * @param renderer the rendererType to set */ public void setRendererType(FacesId renderer) { this.rendererType = renderer; } /** * @return the rendererTemplate */ @Merge public String getRendererTemplate() { return rendererTemplate; } /** * @param rendererTemplate the rendererTemplate to set */ public void setRendererTemplate(String rendererTemplate) { this.rendererTemplate = rendererTemplate; } /** * <p class="changed_added_4_0"> * Reepresent a component family. In the faces-config element that property encoded as * <component><component-extension><cdk:component-family>.... * </p> * * @return the family */ @Merge public FacesId getFamily() { return family; } /** * <p class="changed_added_4_0"> * </p> * * @param family the family to set */ public void setFamily(FacesId family) { this.family = family; } /** * <p class="changed_added_4_0"> * </p> * * @return the facets */ public ModelCollection<FacetModel> getFacets() { return facets; } public FacetModel getFacet(final String name) { return facets.find(new Named.NamePredicate(name)); } public FacetModel getOrCreateFacet(String name) { FacetModel facet = getFacet(name); if (null == facet) { facet = new FacetModel(); facet.setName(name); facets.add(facet); } return facet; } /** * <p class="changed_added_4_0"> * </p> * * @return the events */ public ModelCollection<EventModel> getEvents() { return events; } public EventModel addEvent(ClassName className) { EventModel event = new EventModel(); event.setType(className); events.add(event); return event; } public EventModel addEvent(String className) { return addEvent(ClassName.get(className)); } @Override public String toString() { return "Component {type: " + getId() + ", family: " + getFamily() + "}"; } public void setParent(ComponentModel parentComponent) { this.parent = parentComponent; } @Merge public ComponentModel getParent() { return this.parent; } @Override public void markUnchanged() { this.changed = false; } @Override public boolean hasChanged() { return changed; } @Override public void stopTrackingChanges() { this.changeTracking = false; } }