/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.isis.applib.layout.grid.bootstrap3; import java.util.LinkedHashMap; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.isis.applib.annotation.Programmatic; import org.apache.isis.applib.layout.component.ActionLayoutData; import org.apache.isis.applib.layout.component.CollectionLayoutData; import org.apache.isis.applib.layout.component.DomainObjectLayoutData; import org.apache.isis.applib.layout.component.FieldSet; import org.apache.isis.applib.layout.component.Grid; import org.apache.isis.applib.layout.component.GridAbstract; import org.apache.isis.applib.layout.component.PropertyLayoutData; import org.apache.isis.applib.services.dto.Dto; /** * This is the top-level for rendering the domain object's properties, collections and actions. It simply consists * of a number of rows. * * <p> * The element is rendered as a <div class="..."> * </p> */ @XmlRootElement( name = "grid" ) @XmlType( name = "grid" , propOrder = { "rows", "metadataErrors" } ) public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwner { private static final long serialVersionUID = 1L; private String cssClass; @XmlAttribute(required = false) public String getCssClass() { return cssClass; } public void setCssClass(final String cssClass) { this.cssClass = cssClass; } private List<BS3Row> rows = Lists.newArrayList(); // no wrapper @XmlElement(name = "row", required = true) public List<BS3Row> getRows() { return rows; } public void setRows(final List<BS3Row> rows) { this.rows = rows; } private List<String> metadataErrors = Lists.newArrayList(); /** * For diagnostics; populated by the framework if and only if a metadata error. */ @XmlElement(name = "metadataError", required = false) public List<String> getMetadataErrors() { return metadataErrors; } public void setMetadataErrors(final List<String> metadataErrors) { this.metadataErrors = metadataErrors; } private BS3RowOwner owner; public interface Visitor extends Grid.Visitor { void preVisit(final BS3Grid bs3Grid); void visit(final BS3Grid bs3Grid); void postVisit(final BS3Grid bs3Grid); void preVisit(final BS3Row bs3Row); void visit(final BS3Row bs3Row); void postVisit(final BS3Row bs3Row); void preVisit(final BS3Col bs3Col); void visit(final BS3Col bs3Col); void postVisit(final BS3Col bs3Col); void visit(final BS3ClearFix bs3ClearFix); void preVisit(final BS3TabGroup bs3TabGroup); void visit(final BS3TabGroup bs3TabGroup); void postVisit(final BS3TabGroup bs3TabGroup); void preVisit(final BS3Tab bs3Tab); void visit(final BS3Tab bs3Tab); void postVisit(final BS3Tab bs3Tab); } public static class VisitorAdapter extends Grid.VisitorAdapter implements Visitor { @Override public void preVisit(final BS3Grid bs3Grid) { } @Override public void visit(final BS3Grid bs3Grid) { } @Override public void postVisit(final BS3Grid bs3Grid) { } @Override public void preVisit(final BS3Row bs3Row) { } @Override public void visit(final BS3Row bs3Row) { } @Override public void postVisit(final BS3Row bs3Row) { } @Override public void preVisit(final BS3Col bs3Col) { } @Override public void visit(final BS3Col bs3Col) { } @Override public void postVisit(final BS3Col bs3Col) { } @Override public void visit(final BS3ClearFix bs3ClearFix) { } @Override public void preVisit(final BS3TabGroup bs3TabGroup) { } @Override public void visit(final BS3TabGroup bs3TabGroup) { } @Override public void postVisit(final BS3TabGroup bs3TabGroup) { } @Override public void preVisit(final BS3Tab bs3Tab) { } @Override public void visit(final BS3Tab bs3Tab) { } @Override public void postVisit(final BS3Tab bs3Tab) { } } public void visit(final Grid.Visitor visitor) { final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor); bs3Visitor.preVisit(this); bs3Visitor.visit(this); traverseRows(this, visitor); bs3Visitor.postVisit(this); } protected void traverseRows(final BS3RowOwner rowOwner, final Grid.Visitor visitor) { final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor); final List<BS3Row> rows = rowOwner.getRows(); for (BS3Row bs3Row : Lists.newArrayList(rows)) { bs3Row.setOwner(this); bs3Visitor.preVisit(bs3Row); bs3Visitor.visit(bs3Row); traverseCols(visitor, bs3Row); bs3Visitor.postVisit(bs3Row); } } private void traverseCols(final Grid.Visitor visitor, final BS3Row bs3Row) { final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor); final List<BS3RowContent> cols = bs3Row.getCols(); for (BS3RowContent rowContent : Lists.newArrayList(cols)) { rowContent.setOwner(bs3Row); if(rowContent instanceof BS3Col) { final BS3Col bs3Col = (BS3Col) rowContent; bs3Visitor.preVisit(bs3Col); bs3Visitor.visit(bs3Col); traverseDomainObject(bs3Col, visitor); traverseTabGroups(bs3Col, visitor); traverseActions(bs3Col, visitor); traverseFieldSets(bs3Col, visitor); traverseCollections(bs3Col, visitor); traverseRows(bs3Col, visitor); bs3Visitor.postVisit(bs3Col); } else if (rowContent instanceof BS3ClearFix) { final BS3ClearFix bs3ClearFix = (BS3ClearFix) rowContent; bs3Visitor.visit(bs3ClearFix); } else { throw new IllegalStateException( "Unrecognized implementation of BS3RowContent, " + rowContent); } } } private void traverseDomainObject(final BS3Col bs3Col, final Grid.Visitor visitor) { final DomainObjectLayoutData domainObject = bs3Col.getDomainObject(); if(domainObject == null) { return; } domainObject.setOwner(bs3Col); visitor.visit(domainObject); } private void traverseTabGroups( final BS3TabGroupOwner bs3TabGroupOwner, final Grid.Visitor visitor) { final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor); final List<BS3TabGroup> tabGroups = bs3TabGroupOwner.getTabGroups(); for (BS3TabGroup bs3TabGroup : Lists.newArrayList(tabGroups)) { bs3TabGroup.setOwner(bs3TabGroupOwner); bs3Visitor.preVisit(bs3TabGroup); bs3Visitor.visit(bs3TabGroup); traverseTabs(bs3TabGroup, visitor); bs3Visitor.postVisit(bs3TabGroup); } } private void traverseTabs( final BS3TabOwner bs3TabOwner, final Grid.Visitor visitor) { final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor); final List<BS3Tab> tabs = bs3TabOwner.getTabs(); for (BS3Tab tab : Lists.newArrayList(tabs)) { tab.setOwner(bs3TabOwner); bs3Visitor.preVisit(tab); bs3Visitor.visit(tab); traverseRows(tab, visitor); bs3Visitor.postVisit(tab); } } private static Visitor asBs3Visitor(final Grid.Visitor visitor) { return visitor instanceof Visitor? (Visitor) visitor : new BS3Grid.VisitorAdapter() { @Override public void visit(final DomainObjectLayoutData domainObjectLayoutData) { visitor.visit(domainObjectLayoutData); } @Override public void visit(final ActionLayoutData actionLayoutData) { visitor.visit(actionLayoutData); } @Override public void visit(final PropertyLayoutData propertyLayoutData) { visitor.visit(propertyLayoutData); } @Override public void visit(final CollectionLayoutData collectionLayoutData) { visitor.visit(collectionLayoutData); } @Override public void visit(final FieldSet fieldSet) { visitor.visit(fieldSet); } }; } @Programmatic @XmlTransient public LinkedHashMap<String, BS3Tab> getAllTabsByName() { final LinkedHashMap<String, BS3Tab> tabsByName = Maps.newLinkedHashMap(); visit(new BS3Grid.VisitorAdapter() { @Override public void visit(final BS3Tab bS3Tab) { tabsByName.put(bS3Tab.getName(), bS3Tab); } }); return tabsByName; } @Programmatic @XmlTransient public LinkedHashMap<String, HasCssId> getAllCssId() { final LinkedHashMap<String, HasCssId> divsByCssId = Maps.newLinkedHashMap(); visit(new BS3Grid.VisitorAdapter() { @Override public void visit(final BS3Row bs3Row) { final String id = bs3Row.getId(); divsByCssId.put(id, bs3Row); } }); return divsByCssId; } @Override @Programmatic @XmlTransient public BS3Grid getGrid() { return this; } }