| /* |
| * Copyright 2009 Google Inc. |
| * |
| * Licensed 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 com.google.gwt.uibinder.elementparsers; |
| |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.uibinder.rebind.UiBinderWriter; |
| import com.google.gwt.uibinder.rebind.XMLElement; |
| |
| /** |
| * Parses {@link com.google.gwt.user.client.ui.DisclosurePanel} widgets. |
| */ |
| public class DisclosurePanelParser implements ElementParser { |
| |
| private static class Children { |
| XMLElement body; |
| XMLElement header; |
| XMLElement customHeader; |
| } |
| |
| private static final String CUSTOM = "customHeader"; |
| private static final String HEADER = "header"; |
| private static final String OPEN_IMAGE = "openImage"; |
| private static final String CLOSED_IMAGE = "closedImage"; |
| |
| public void parse(final XMLElement panelElem, String panelField, |
| JClassType type, final UiBinderWriter writer) |
| throws UnableToCompleteException { |
| Children children = findChildren(panelElem, writer); |
| |
| if (null != children.body) { |
| if (!writer.isWidgetElement(children.body)) { |
| writer.die(children.body, "Must be a widget"); |
| } |
| |
| String bodyField = writer.parseElementToField(children.body); |
| writer.addInitStatement("%s.add(%s);", panelField, bodyField); |
| } |
| |
| if (null != children.customHeader) { |
| XMLElement headerElement = children.customHeader.consumeSingleChildElement(); |
| |
| if (!writer.isWidgetElement(headerElement)) { |
| writer.die(headerElement, "Must be a widget"); |
| } |
| |
| String headerField = writer.parseElementToField(headerElement); |
| writer.addInitStatement("%s.setHeader(%s);", panelField, headerField); |
| } |
| |
| if (null != children.header) { |
| String openImage = children.header.consumeImageResourceAttribute(OPEN_IMAGE); |
| String closedImage = children.header.consumeImageResourceAttribute(CLOSED_IMAGE); |
| String headerText = children.header.consumeInnerTextEscapedAsHtmlStringLiteral(new TextInterpreter( |
| writer)); |
| |
| if ((openImage == null) ^ (closedImage == null)) { |
| writer.die(children.header, |
| "Both %s and %s must be specified, or neither", OPEN_IMAGE, |
| CLOSED_IMAGE); |
| } |
| |
| String panelTypeName = type.getQualifiedSourceName(); |
| if (openImage != null) { |
| writer.setFieldInitializer(panelField, String.format( |
| "new %s(%s, %s, \"%s\")", panelTypeName, openImage, closedImage, |
| headerText)); |
| } else { |
| writer.setFieldInitializer(panelField, String.format("new %s(\"%s\")", |
| panelTypeName, headerText)); |
| } |
| } |
| } |
| |
| private Children findChildren(final XMLElement elem, |
| final UiBinderWriter writer) throws UnableToCompleteException { |
| final Children children = new Children(); |
| |
| elem.consumeChildElements(new XMLElement.Interpreter<Boolean>() { |
| public Boolean interpretElement(XMLElement child) |
| throws UnableToCompleteException { |
| |
| if (hasAttribute(child, HEADER)) { |
| assertFirstHeader(); |
| children.header = child; |
| return true; |
| } |
| |
| if (hasAttribute(child, CUSTOM)) { |
| assertFirstHeader(); |
| children.customHeader = child; |
| return true; |
| } |
| |
| // Must be the body, then |
| if (null != children.body) { |
| writer.die(elem, "May have only one body element"); |
| } |
| |
| children.body = child; |
| return true; |
| } |
| |
| void assertFirstHeader() throws UnableToCompleteException { |
| if ((null != children.header) && (null != children.customHeader)) { |
| writer.die(elem, "May have only one %2$s:header " |
| + "or %2$s:customHeader", elem.getPrefix()); |
| } |
| } |
| |
| private boolean hasAttribute(XMLElement child, final String attribute) { |
| return rightNamespace(child) && child.getLocalName().equals(attribute); |
| } |
| |
| private boolean rightNamespace(XMLElement child) { |
| return child.getNamespaceUri().equals(elem.getNamespaceUri()); |
| } |
| }); |
| |
| return children; |
| } |
| } |