Package org.reverspring.xml

Source Code of org.reverspring.xml.XmlGenerator

/*
* Copyright 2007 Luigi Dell'Aquila (luigi.dellaquila@assetdata.it)
*
* 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.reverspring.xml;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.reverspring.engine.BeanDescriptor;
import org.reverspring.engine.BeanSet;
import org.reverspring.engine.DescriptorGenerator;
import org.reverspring.engine.ObjectBinding;

/**
* This class provides mehods to generate Spring IoC XML descriptors from {@link BeanSet} objects.
*
* @see BeanSet
* @see DescriptorGenerator
*
* @author Luigi Dell'Aquila
*
*/
public class XmlGenerator {

  private static char[]  ODD_CHARS  = new char[] { '&', '<', '>' };

  /**
   * generates an xml document from a bean set
   *
   * @param beanSet
   *          the bean set containing the description of the beans to be written in the descriptor
   * @return a Spring xml descriptor
   */
  public static String getXml(BeanSet beanSet) {
    StringBuffer buffer = new StringBuffer();
    buffer.append("<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\" ");
    buffer.append("\"http://www.springframework.org/dtd/spring-beans.dtd\">\n");
    buffer.append("<beans default-lazy-init=\"true\" default-autowire=\"no\">\n");

    Set<String> beansProcessed = new HashSet<String>();
    for (BeanDescriptor descriptor : beanSet.getBeans()) {
      if (descriptor.getType() != BeanDescriptor.TYPE_LIST && descriptor.getType() != BeanDescriptor.TYPE_SET
          && descriptor.getType() != BeanDescriptor.TYPE_MAP) {
        if (!beansProcessed.contains(descriptor.getId()))
          writeBean(descriptor, buffer, beansProcessed, 1);
      }
    }

    buffer.append("</beans>");
    return buffer.toString();
  }

  /**
   * generates an XML document from a bean set and saves it on a file
   *
   * @param beanSet
   *          the bean set containing the description of the beans to be written in the descriptor
   * @param file
   *          the file where to save the xml
   * @throws IOException
   */
  public static void save(BeanSet beanSet, File file) throws IOException {
    FileWriter writer = new FileWriter(file);
    writer.write(XmlGenerator.getXml(beanSet));
    writer.flush();
    writer.close();
  }

  private static void pad(int steps, StringBuffer buffer) {
    for (int i = 0; i < steps; i++) {
      buffer.append("  ");
    }
  }

  private static void writeBean(BeanDescriptor descriptor, StringBuffer buffer, Set<String> beansProcessed, int indent) {
    pad(indent, buffer);
    buffer.append("<bean ");
    buffer.append("class=\"" + descriptor.getBean().getClass().getName() + "\" ");
    buffer.append("id=\"" + descriptor.getId() + "\">\n");
    beansProcessed.add(descriptor.getId());

    // constructor
    if (descriptor.getConstructorArguments() != null && descriptor.getConstructorArguments().length > 0) {
      for (ObjectBinding binding : descriptor.getConstructorArguments()) {
        XmlGenerator.writeConstructorArg(binding, buffer, beansProcessed, indent + 1);
      }
    }

    for (String propertyName : descriptor.getProperties()) {
      if (descriptor.getBinding(propertyName) != null
          && descriptor.getBinding(propertyName).getDescriptor().getType() == BeanDescriptor.TYPE_BASE) {
        boolean inline = descriptor.getBinding(propertyName).isNested();
        XmlGenerator.writeSimpleProperty(propertyName, descriptor.getBinding(propertyName).getDescriptor().getBean().toString(),
            inline, buffer, indent + 1);
      } else if (descriptor.getBinding(propertyName) != null) {
        XmlGenerator.writeRefProperty(propertyName, descriptor.getBinding(propertyName), beansProcessed, buffer, indent + 1);
      } else if (descriptor.getListProperty(propertyName) != null) {// list of objects
        XmlGenerator.writeListProperty(propertyName, descriptor.getListProperty(propertyName), beansProcessed, buffer, indent + 1);
      } else if (descriptor.getSetProperty(propertyName) != null) {// set of objects
        XmlGenerator.writeSetProperty(propertyName, descriptor.getSetProperty(propertyName), beansProcessed, buffer, indent + 1);
      } else if (descriptor.getMapProperty(propertyName) != null) {
        XmlGenerator.writeMapProperty(propertyName, descriptor.getMapProperty(propertyName), beansProcessed, buffer, indent + 1);
      } else { // null value
        XmlGenerator.writeSimpleProperty(propertyName, null, false, buffer, indent + 1);
      }
    }

    pad(indent, buffer);
    buffer.append("</bean>\n");
  }

  private static void writeConstructorArg(ObjectBinding argument, StringBuffer buffer, Set<String> beansProcessed, int indent) {
    pad(indent, buffer);
    buffer.append("<constructor-arg>\n");
    if (argument.getDescriptor().getBean() == null) {
      buffer.append("<null/>\n");
    } else if (argument.getDescriptor().getType() == BeanDescriptor.TYPE_BASE) {
      writeSimplePropertyValue(argument, buffer, indent + 1);
    } else {
      writeRef(argument.getDescriptor().getId(), buffer, indent + 1);
    }
    pad(indent, buffer);
    buffer.append("</constructor-arg>\n");
  }

  private static void writeSetProperty(String propertyName, Set<ObjectBinding> value, Set<String> beansProcessed,
      StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<property name=\"" + propertyName + "\">\n");
    writeSetContent(value, beansProcessed, buffer, indent + 1);
    pad(indent, buffer);
    buffer.append("</property>\n");
  }

  private static void writeSetContent(Set<ObjectBinding> value, Set<String> beansProcessed, StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<set>\n");
    if (value != null) {
      for (ObjectBinding ref : value) {
        BeanDescriptor descriptor = ref.getDescriptor();
        if (descriptor.getType() == BeanDescriptor.TYPE_BASE) {
          writeSimplePropertyValue(ref, buffer, indent + 1);
        } else {
          if (ref.isNested() && !beansProcessed.contains(ref.getDescriptor().getId())) {
            writeBean(descriptor, buffer, beansProcessed, indent + 1);
          } else {
            writeRef(descriptor.getId(), buffer, indent + 1);
          }
        }
      }
    }
    pad(indent, buffer);
    buffer.append("</set>\n");
  }

  private static void writeListProperty(String propertyName, List<ObjectBinding> value, Set<String> beansProcessed,
      StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<property name=\"" + propertyName + "\">\n");
    writeListContent(value, beansProcessed, buffer, indent + 1);
    pad(indent, buffer);
    buffer.append("</property>\n");
  }

  private static void writeListContent(List<ObjectBinding> value, Set<String> beansProcessed, StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<list>\n");
    if (value != null) {
      for (ObjectBinding ref : value) {
        BeanDescriptor descriptor = ref.getDescriptor();
        if (descriptor.getType() == BeanDescriptor.TYPE_BASE) {
          writeSimplePropertyValue(ref, buffer, indent + 1);
        } else if (ref.getDescriptor().getType() == BeanDescriptor.TYPE_LIST) {
          writeListContent(ref.getDescriptor().getListProperty(BeanDescriptor.PROPERTY_CONTENT), beansProcessed, buffer, indent + 1);
        } else if (ref.getDescriptor().getType() == BeanDescriptor.TYPE_SET) {
          writeSetContent(ref.getDescriptor().getSetProperty(BeanDescriptor.PROPERTY_CONTENT), beansProcessed, buffer, indent + 1);
        } else if (ref.getDescriptor().getType() == BeanDescriptor.TYPE_MAP) {
          writeMapContent(ref.getDescriptor().getMapProperty(BeanDescriptor.PROPERTY_CONTENT), beansProcessed, buffer, indent + 1);
        } else {
          if (ref.isNested() && !beansProcessed.contains(ref.getDescriptor().getId())) {
            writeBean(descriptor, buffer, beansProcessed, indent + 1);
          } else {
            writeRef(descriptor.getId(), buffer, indent + 1);
          }
        }
      }
    }
    pad(indent, buffer);
    buffer.append("</list>\n");
  }

  private static void writeMapProperty(String propertyName, Map<ObjectBinding, ObjectBinding> value, Set<String> beansProcessed,
      StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<property name=\"" + propertyName + "\">\n");
    writeMapContent(value, beansProcessed, buffer, indent + 1);
    pad(indent, buffer);
    buffer.append("</property>\n");
  }

  private static void writeMapContent(Map<ObjectBinding, ObjectBinding> value, Set<String> beansProcessed, StringBuffer buffer,
      int indent) {
    pad(indent, buffer);
    buffer.append("<map>\n");
    for (ObjectBinding mapKey : value.keySet()) {
      ObjectBinding mapValue = value.get(mapKey);
      pad(indent + 1, buffer);
      buffer.append("<entry>\n");
      pad(indent + 2, buffer);
      buffer.append("<key>\n");
      if (mapKey.getDescriptor().getType() == BeanDescriptor.TYPE_BASE) {
        writeSimplePropertyValue(mapKey, buffer, indent + 3);
      } else {
        if (mapKey.isNested() && !beansProcessed.contains(mapKey.getDescriptor().getId()))
          writeBean(mapKey.getDescriptor(), buffer, beansProcessed, indent + 3);
        else
          writeRef(mapKey.getDescriptor().getId(), buffer, indent + 3);
      }
      pad(indent + 2, buffer);
      buffer.append("</key>\n");

      if (mapValue.getDescriptor().getBean() == null) {
        writeNull(buffer, indent + 2);
      } else if (mapValue.getDescriptor().getType() == BeanDescriptor.TYPE_BASE) {
        writeSimplePropertyValue(mapValue, buffer, indent + 2);
      } else if (mapValue.getDescriptor().getType() == BeanDescriptor.TYPE_LIST) {
        writeListContent(mapValue.getDescriptor().getListProperty(BeanDescriptor.PROPERTY_CONTENT), beansProcessed, buffer,
            indent + 2);
      } else if (mapValue.getDescriptor().getType() == BeanDescriptor.TYPE_SET) {
        writeSetContent(mapValue.getDescriptor().getSetProperty(BeanDescriptor.PROPERTY_CONTENT), beansProcessed, buffer,
            indent + 2);
      } else if (mapValue.getDescriptor().getType() == BeanDescriptor.TYPE_MAP) {
        writeMapContent(mapValue.getDescriptor().getMapProperty(BeanDescriptor.PROPERTY_CONTENT), beansProcessed, buffer,
            indent + 2);
      } else {
        if (mapValue.isNested() && !beansProcessed.contains(mapValue.getDescriptor().getId())) {
          writeBean(mapValue.getDescriptor(), buffer, beansProcessed, indent + 2);
        } else {
          writeRef(mapValue.getDescriptor().getId(), buffer, indent + 2);
        }
      }
      pad(indent + 1, buffer);
      buffer.append("</entry>\n");
    }
    pad(indent, buffer);
    buffer.append("</map>\n");
  }

  private static void writeSimplePropertyValue(ObjectBinding actualValue, StringBuffer buffer, int indent) {
    Object bean = actualValue.getDescriptor().getBean();
    if (bean == null) {
      writeNull(buffer, indent);
      return;
    }
    pad(indent, buffer);
    buffer.append("<value");
    if (actualValue.getDescriptor().getType() == BeanDescriptor.TYPE_BASE) {
      buffer.append(" type=\"" + bean.getClass().getName() + "\"");
    }
    buffer.append(">");
    buffer.append(bean.toString());
    buffer.append("</value>\n");
  }

  private static void writeSimpleProperty(String name, String value, boolean inline, StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<property name=\"" + name + "\">\n");
    if (value != null) {
      pad(indent + 1, buffer);
      buffer.append("<value>");
      if (containsOddChars(value)) {
        buffer.append("<![CDATA[");
        buffer.append(value);
        buffer.append("]]>");
      } else {
        buffer.append(value);
      }
      buffer.append("</value>\n");
    } else {
      writeNull(buffer, indent + 1);
    }
    pad(indent, buffer);
    buffer.append("</property>\n");
  }

  private static boolean containsOddChars(String value) {
    for (char c : ODD_CHARS)
      if (value.indexOf(c) > -1) {
        return true;
      }
    return false;
  }

  private static void writeRefProperty(String name, ObjectBinding binding, Set<String> beansProcessed, StringBuffer buffer,
      int indent) {
    pad(indent, buffer);
    buffer.append("<property name=\"" + name + "\">\n");
    writeRef(binding.getDescriptor().getId(), buffer, indent + 1);
    pad(indent, buffer);
    buffer.append("</property>\n");
  }

  private static void writeRef(String id, StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<ref bean=\"" + id + "\" />\n");
  }

  private static void writeNull(StringBuffer buffer, int indent) {
    pad(indent, buffer);
    buffer.append("<null/>\n");
  }
}
TOP

Related Classes of org.reverspring.xml.XmlGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.