Java tutorial
/* * Copyright (C) 2011 Rhegium Team * * 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 org.rhegium.vaadin.internal.mvc; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Stack; import org.rhegium.api.mvc.View; import org.rhegium.api.typeconverter.TypeConverterManager; import org.rhegium.api.uibinder.TargetHandler; import org.rhegium.api.uibinder.UiBinderException; import org.rhegium.internal.utils.ReflectionUtils; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.Panel; class ComponentHandler implements TargetHandler { private final Map<String, String> packages = new HashMap<String, String>(); private final Stack<Component> components = new Stack<Component>(); private final Map<Component, Float> expandRatios = new HashMap<Component, Float>(); private final TypeConverterManager typeConverterManager; private final VaadinUiBinderService binderService; private final View<Component, ?, ?> view; private final Locale locale; private Component currentComponent = null; ComponentHandler(VaadinUiBinderService binderService, View<Component, ?, ?> view, Locale locale, TypeConverterManager typeConverterManager) { this.typeConverterManager = typeConverterManager; this.binderService = binderService; this.view = view; this.locale = locale; this.currentComponent = view.getComponent(); } @Override public String getTargetNamespace() { return null; } @Override public void handleStartElement(String uri, String name) { components.push(currentComponent); String packageName = getPackageNameByUri(uri); String viewName = packageName + "." + name; try { if (binderService.isBindable(viewName)) { currentComponent = binderService.bind(viewName, view, locale); } else { Class<?> clazz = Class.forName(viewName); currentComponent = (Component) clazz.newInstance(); } } catch (ClassNotFoundException e) { throw new UiBinderException(e); } catch (InstantiationException e) { throw new UiBinderException(e); } catch (IllegalAccessException e) { throw new UiBinderException(e); } } @Override public void handleEndElement(String uri, String name) { Component innerComponent = currentComponent; currentComponent = components.pop(); if (currentComponent instanceof Panel && innerComponent instanceof ComponentContainer) { ((Panel) currentComponent).setContent((ComponentContainer) innerComponent); } else if (currentComponent instanceof ComponentContainer) { ((ComponentContainer) currentComponent).addComponent(innerComponent); } if (expandRatios.size() > 0) { Iterator<Entry<Component, Float>> iterator = expandRatios.entrySet().iterator(); while (iterator.hasNext()) { Entry<Component, Float> entry = iterator.next(); Component expandingComponent = entry.getKey(); if (innerComponent != expandingComponent) { continue; } Component parentComponent = expandingComponent.getParent(); if (!(parentComponent instanceof AbstractOrderedLayout)) { throw new UiBinderException("Cannot set expandRatio for element " + expandingComponent + " since parent is no OrderedLayout"); } Float expandRatio = entry.getValue(); ((AbstractOrderedLayout) parentComponent).setExpandRatio(expandingComponent, expandRatio); iterator.remove(); } } } @Override public void handleAttribute(String name, Object value) { if (currentComponent == null) { return; } if ("expandRatio".equals(name)) { expandRatios.put(currentComponent, Float.parseFloat(value.toString())); } else { ReflectionUtils.injectValue(name, value, currentComponent, typeConverterManager); } } Component getCurrentComponent() { return currentComponent; } Component getRootComponent() { return components.get(0); } private String getPackageNameByUri(String uri) { if (packages.containsKey(uri)) { return packages.get(uri); } try { URI namespace = new URI(uri); if ("urn".equals(namespace.getScheme())) { String packageName = namespace.getSchemeSpecificPart(); if (packageName.startsWith("import:")) { packageName = packageName.substring(7); } packages.put(uri, packageName); return packageName; } throw new UiBinderException("Illegal URI scheme for uri: " + uri); } catch (URISyntaxException e) { throw new UiBinderException(e); } } }