blob: 4ee9dfb4948b4d109165175623cadafdeb89eb81 [file] [log] [blame]
/*
* 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)
);
}
}