/* * Copyright 2000-2009 JetBrains s.r.o. * * 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.intellij.uiDesigner; import com.intellij.openapi.diagnostic.Logger; import com.intellij.ui.JBColor; import com.intellij.uiDesigner.compiler.RecursiveFormNestingException; import com.intellij.uiDesigner.compiler.Utils; import com.intellij.uiDesigner.lw.*; import com.intellij.uiDesigner.make.PsiNestedFormLoader; import com.intellij.uiDesigner.palette.Palette; import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; import com.intellij.uiDesigner.radComponents.*; import com.intellij.uiDesigner.shared.XYLayoutManager; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.text.MessageFormat; import java.util.HashMap; import java.util.Locale; import java.util.Map; /** * @author Anton Katilin * @author Vladimir Kondratyev */ public final class XmlReader { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.XmlReader"); private XmlReader() { } @NotNull public static RadRootContainer createRoot(final ModuleProvider module, final LwRootContainer lwRootContainer, final ClassLoader loader, final Locale stringDescriptorLocale) throws Exception{ return (RadRootContainer)createComponent(module, lwRootContainer, loader, stringDescriptorLocale); } @NotNull public static RadComponent createComponent(@NotNull final ModuleProvider module, @NotNull final LwComponent lwComponent, @NotNull final ClassLoader loader, final Locale stringDescriptorLocale) throws Exception{ // Id final String id = lwComponent.getId(); final RadComponent component; Class componentClass = null; if (lwComponent instanceof LwNestedForm) { LwNestedForm nestedForm = (LwNestedForm) lwComponent; boolean recursiveNesting = false; try { Utils.validateNestedFormLoop(nestedForm.getFormFileName(), new PsiNestedFormLoader(module.getModule())); } catch(RecursiveFormNestingException ex) { recursiveNesting = true; } if (recursiveNesting) { component = RadErrorComponent.create( module, id, lwComponent.getComponentClassName(), lwComponent.getErrorComponentProperties(), UIDesignerBundle.message("error.recursive.form.nesting")); } else { component = new RadNestedForm(module, nestedForm.getFormFileName(), id); } } else { if (lwComponent.getErrorComponentProperties() == null) { componentClass = Class.forName(lwComponent.getComponentClassName(), true, loader); } if (lwComponent instanceof LwHSpacer) { component = new RadHSpacer(module, id); } else if (lwComponent instanceof LwVSpacer) { component = new RadVSpacer(module, id); } else if (lwComponent instanceof LwAtomicComponent) { if (componentClass == null) { component = createErrorComponent(module, id, lwComponent, loader); } else { RadComponent component1; try { if (JTable.class.isAssignableFrom(componentClass)) { component1 = new RadTable(module, componentClass, id); } else { component1 = new RadAtomicComponent(module, componentClass, id); } } catch (final Exception exc) { String errorDescription = MessageFormat.format(UIDesignerBundle.message("error.class.cannot.be.instantiated"), lwComponent.getComponentClassName()); final String message = FormEditingUtil.getExceptionMessage(exc); if (message != null) { errorDescription += ": " + message; } component1 = RadErrorComponent.create( module, id, lwComponent.getComponentClassName(), lwComponent.getErrorComponentProperties(), errorDescription ); } component = component1; } } else if (lwComponent instanceof LwScrollPane) { component = new RadScrollPane(module, componentClass, id); } else if (lwComponent instanceof LwTabbedPane) { component = new RadTabbedPane(module, componentClass, id); } else if (lwComponent instanceof LwSplitPane) { component = new RadSplitPane(module, componentClass, id); } else if (lwComponent instanceof LwToolBar) { component = new RadToolBar(module, componentClass, id); } else if (lwComponent instanceof LwContainer) { final LwContainer lwContainer = (LwContainer)lwComponent; LayoutManager layout = lwContainer.getLayout(); if (layout instanceof XYLayoutManager) { // replace stub layout with the real one final XYLayoutManagerImpl xyLayoutManager = new XYLayoutManagerImpl(); layout = xyLayoutManager; xyLayoutManager.setPreferredSize(lwComponent.getBounds().getSize()); } if (componentClass == null) { component = createErrorComponent(module, id, lwComponent, loader); } else { if (lwContainer instanceof LwRootContainer) { component = new RadRootContainer(module, id); if (stringDescriptorLocale != null) { ((RadRootContainer) component).setStringDescriptorLocale(stringDescriptorLocale); } } else { component = new RadContainer(module, componentClass, id); String layoutManagerName = lwContainer.getLayoutManager(); if (layoutManagerName == null || layoutManagerName.length() == 0) { if (layout instanceof XYLayoutManager) { layoutManagerName = UIFormXmlConstants.LAYOUT_XY; } else { layoutManagerName = UIFormXmlConstants.LAYOUT_INTELLIJ; } } RadLayoutManager layoutManager = LayoutManagerRegistry.createLayoutManager(layoutManagerName); RadContainer container = (RadContainer)component; layoutManager.readLayout(lwContainer, container); container.setLayoutManager(layoutManager); } ((RadContainer)component).setLayout(layout); } } else { throw new IllegalArgumentException("unexpected component: " + lwComponent); } } // binding component.setBinding(lwComponent.getBinding()); component.setCustomCreate(lwComponent.isCustomCreate()); component.setDefaultBinding(lwComponent.isDefaultBinding()); // bounds component.setBounds(lwComponent.getBounds()); // properties if (stringDescriptorLocale != null) { component.putClientProperty(RadComponent.CLIENT_PROP_LOAD_TIME_LOCALE, stringDescriptorLocale); } final LwIntrospectedProperty[] properties = lwComponent.getAssignedIntrospectedProperties(); if (componentClass != null) { final Palette palette = Palette.getInstance(module.getProject()); for (final LwIntrospectedProperty lwProperty : properties) { final IntrospectedProperty property = palette.getIntrospectedProperty(component, lwProperty.getName()); if (property == null) { continue; } component.loadLwProperty(lwComponent, lwProperty, property); } } // GridConstraints component.getConstraints().restore(lwComponent.getConstraints()); component.setCustomLayoutConstraints(lwComponent.getCustomLayoutConstraints()); HashMap clientProps = lwComponent.getDelegeeClientProperties(); for(Object o: clientProps.entrySet()) { Map.Entry entry = (Map.Entry) o; Object value = entry.getValue(); if (value instanceof StringDescriptor) { value = ((StringDescriptor) value).getValue(); } component.getDelegee().putClientProperty(entry.getKey(), value); } if (component instanceof RadContainer) { final RadContainer container = (RadContainer)component; //noinspection ConstantConditions final LwContainer lwContainer = (LwContainer)lwComponent; copyBorder(container, lwContainer); // add children for (int i=0; i < lwContainer.getComponentCount(); i++){ container.addComponent(createComponent(module, (LwComponent)lwContainer.getComponent(i), loader, stringDescriptorLocale)); } } if (component instanceof RadRootContainer) { final RadRootContainer radRootContainer = (RadRootContainer)component; //noinspection ConstantConditions final LwRootContainer lwRootContainer = (LwRootContainer)lwComponent; radRootContainer.setClassToBind(lwRootContainer.getClassToBind()); radRootContainer.setMainComponentBinding(lwRootContainer.getMainComponentBinding()); radRootContainer.setButtonGroups(lwRootContainer.getButtonGroups()); radRootContainer.setInspectionSuppressions(lwRootContainer.getInspectionSuppressions()); radRootContainer.getDelegee().setBackground(new JBColor(Color.WHITE, UIUtil.getListBackground())); } component.doneLoadingFromLw(); component.putClientProperty(RadComponent.CLIENT_PROP_LOAD_TIME_LOCALE, null); return component; } private static void copyBorder(final RadContainer container, final LwContainer lwContainer) { container.setBorderType(lwContainer.getBorderType()); container.setBorderTitle(lwContainer.getBorderTitle()); container.setBorderTitleJustification(lwContainer.getBorderTitleJustification()); container.setBorderTitlePosition(lwContainer.getBorderTitlePosition()); container.setBorderTitleFont(lwContainer.getBorderTitleFont()); container.setBorderTitleColor(lwContainer.getBorderTitleColor()); container.setBorderSize(lwContainer.getBorderSize()); container.setBorderColor(lwContainer.getBorderColor()); } private static RadErrorComponent createErrorComponent(final ModuleProvider module, final String id, final LwComponent lwComponent, final ClassLoader loader) { final String componentClassName = lwComponent.getComponentClassName(); final String errorDescription = Utils.validateJComponentClass(loader, componentClassName, true); return RadErrorComponent.create( module, id, lwComponent.getComponentClassName(), lwComponent.getErrorComponentProperties(), errorDescription != null? errorDescription : UIDesignerBundle.message("error.cannot.load.class", componentClassName) ); } }