Package nexj.core.tools

Source Code of nexj.core.tools.XSDMessageTool

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.tools;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import nexj.core.meta.Metadata;
import nexj.core.meta.MetadataLoaderDispatcher;
import nexj.core.meta.MetadataObject;
import nexj.core.meta.Repository;
import nexj.core.meta.integration.Channel;
import nexj.core.meta.integration.Message;
import nexj.core.meta.integration.format.xml.XSDMessageExporter;
import nexj.core.meta.integration.format.xml.XSDMessageImporter;
import nexj.core.meta.integration.service.Interface;
import nexj.core.meta.xml.XMLMetadataExporter;
import nexj.core.meta.xml.XMLMetadataLoader;
import nexj.core.runtime.InvocationContext;
import nexj.core.util.IOUtil;
import nexj.core.util.Logger;
import nexj.core.util.URIUtil;
import nexj.core.util.URLUtil;
import nexj.core.util.XMLUtil;

/**
* Exports/imports Messages to/from XSD and WSDL.
*/
public class XSDMessageTool extends GenericTool
{
   // constants

   /**
    * No operation command.
    */
   protected final static int COMMAND_NOP = 0;

   /**
    * Import XSD to Messages.
    */
   protected final static int COMMAND_IMPORT = 1;

   /**
    * Export Messages to XSD/WSDL.
    */
   protected final static int COMMAND_EXPORT = 2;

   /**
    * Export Channel to XSD/WSDL.
    */
   protected final static int COMMAND_EXPORT_CHANNEL = 3;

   /**
    * Export Interface to XSD/WSDL.
    */
   protected final static int COMMAND_EXPORT_INTERFACE = 4;


   // attributes

   /**
    * The command to execute, one of the COMMAND_* constants.
    */
   protected int m_nCommand = COMMAND_NOP;

   /**
    * An optional prefix to use for output message file names.
    */
   private String m_sOptionalFilePrefix;


   // associations

   /**
    * The items (from the command arguments) to import/export.
    */
   protected List m_itemList;

   /**
    * Directory for .message file output.
    */
   private File m_targetDir;

   /**
    * The metadata repository.
    */
   protected Metadata m_metadata;

   /**
    * The invocation context.
    */
   protected InvocationContext m_context;

   /**
    * The class logger.
    */
   public final static Logger s_logger = Logger.getLogger(XSDMessageTool.class);


   // operations

   /**
    * @see nexj.core.tools.GenericTool#execute(java.lang.String)
    */
   protected void execute(String sCommand) throws Exception
   {
      if (sCommand != null)
      {
         if (m_nCommand == COMMAND_NOP)
         {
            // First argument is always the command
            if ("import".equals(sCommand))
            {
               m_nCommand = COMMAND_IMPORT;
            }
            else if ("export".equals(sCommand))
            {
               m_nCommand = COMMAND_EXPORT;
            }
            else if ("exportchannel".equals(sCommand))
            {
               m_nCommand = COMMAND_EXPORT_CHANNEL;
            }
            else if ("exportinterface".equals(sCommand))
            {
               m_nCommand = COMMAND_EXPORT_INTERFACE;
            }
            else
            {
               throw new IllegalStateException("Unknown command: " + sCommand);
            }
         }
         else
         {
            if (m_itemList == null)
            {
               m_itemList = new ArrayList();
            }

            m_itemList.add(sCommand);
         }
      }
   }

   /**
    * @see nexj.core.tools.GenericTool#end()
    */
   protected void end() throws Exception
   {
      if (m_nCommand == COMMAND_IMPORT)
      {
         if (m_itemList == null)
         {
            executeImport(null);
         }
         else
         {
            for (Iterator itr = m_itemList.iterator(); itr.hasNext(); )
            {
               executeImport((String)itr.next());
            }
         }
      }
      else
      {
         if (m_itemList == null || m_itemList.size() != 1)
         {
            throw new IllegalArgumentException("Must specify *one* metadata object after export command");
         }

         String sMetaName = (String)m_itemList.get(0);
         MetadataObject metaObj;

         m_metadata = new MetadataLoaderDispatcher().load(null, null, XMLMetadataLoader.DOCUMENTATION_INCLUDED, null);
         m_context = (InvocationContext)m_metadata.getComponent("System.InvocationContext").getInstance(null);

         switch (m_nCommand)
         {
            case COMMAND_EXPORT:
               metaObj = m_metadata.getMessage(sMetaName);
               break;

            case COMMAND_EXPORT_CHANNEL:
               metaObj = m_metadata.getChannel(sMetaName);
               break;

            case COMMAND_EXPORT_INTERFACE:
               metaObj = m_metadata.getInterface(sMetaName);
               break;

            default:
               throw new IllegalStateException();
         }

         executeExport(metaObj);
      }
   }

   /**
    * Exports a Message, Interface, or Channel metadata object to an
    * XSD or WSDL file.
    *
    * @param metaObj The metadata object to export.
    * @throws Exception If an error occurs.
    */
   protected void executeExport(MetadataObject metaObj) throws Exception
   {
      XSDMessageExporter exporter = new XSDMessageExporter(m_context);
      String sFile;
      File file;

      if (hasProperty("xsd.file"))
      {
         sFile = getProperty("xsd.file");
         exporter.setOutputMode(XSDMessageExporter.OUTMODE_XSD);
      }
      else if (hasProperty("wsdl.file"))
      {
         sFile = getProperty("wsdl.file");
         exporter.setOutputMode(XSDMessageExporter.OUTMODE_WSDL);

         if (hasProperty("wsdl.host"))
         {
            exporter.setHostName(getProperty("wsdl.host"));
         }
         else
         {
            exporter.setHostName(URIUtil.getHostPort(m_metadata.getHTTPRoot()));
         }

         if (hasProperty("wsdl.httpRoot"))
         {
            exporter.setContextRoot(getProperty("wsdl.httpRoot"));
         }
         else
         {
            exporter.setContextRoot(m_metadata.getHTTPContextRoot());
         }
      }
      else
      {
         throw new IllegalArgumentException("Missing required property xsd.file or wsdl.file");
      }

      if (URLUtil.isURL(sFile))
      {
         file = URLUtil.fileFromURL(new URL(sFile));
      }
      else
      {
         file = new File(sFile);
      }

      Writer writer = null;

      try
      {
         writer = IOUtil.openBufferedWriter(file, XMLUtil.ENCODING);

         if (metaObj instanceof Channel)
         {
            exporter.export((Channel)metaObj, writer);
         }
         else if (metaObj instanceof Interface)
         {
            exporter.export((Interface)metaObj, writer);
         }
         else if (metaObj instanceof Message)
         {
            exporter.export((Message)metaObj, writer);
         }
         else
         {
            throw new IllegalArgumentException();
         }
      }
      finally
      {
         if (writer != null)
         {
            writer.close();
         }
      }
   }

   /**
    * Imports an XSD or WSDL file to Message metadata.
    *
    * @param sRootElement Import only this top-level element from the schema; null
    *                     to import all top-level elements from the schema.
    * @throws Exception If an error occurs.
    */
   protected void executeImport(String sRootElement) throws Exception
   {
      String sFile = null;

      if (hasProperty("xsd.file"))
      {
         sFile = getRequiredProperty("xsd.file");
      }
      else if (hasProperty("wsdl.file"))
      {
         sFile = getRequiredProperty("wsdl.file");
      }
      else
      {
         throw new IllegalArgumentException("Missing required property xsd.file or wsdl.file");
      }

      URL xsdURL;

      if (URLUtil.isURL(sFile))
      {
         xsdURL = new URL(sFile);
      }
      else
      {
         File file = new File(sFile);
        
         if (!file.isFile() || !file.exists())
         {
            throw new IllegalArgumentException("Invalid XSD file or URL");
         }

         xsdURL = file.toURL();
      }
     
      m_targetDir = new File(getRequiredProperty("out.dir"));
     
      if (!m_targetDir.isDirectory() || !m_targetDir.exists())
      {
         throw new IllegalArgumentException("Target directory is invalid or does not exist");
      }
     
      m_sOptionalFilePrefix = getProperty("msg.prefix");
     
      Metadata metadata = Repository.getMetadata();

      Message[] messages;
     
      final XSDMessageImporter.MessageNameResolver fMsgNameResolver = new XSDMessageImporter.MessageNameResolver()
      {
         /**
          * @see nexj.core.meta.integration.format.xml.XSDMessageImporter.MessageNameResolver#resolveName(java.lang.String)
          */
         public String resolveName(String defName)
         {
            return (m_sOptionalFilePrefix == null) ? defName :
               m_sOptionalFilePrefix + defName;
         }
      };
     
      if (sRootElement == null)
      {
         messages = XSDMessageImporter.createMessageParts(xsdURL, metadata, fMsgNameResolver);
      }
      else
      {
         Message part = XSDMessageImporter.createMessagePart(xsdURL, metadata, sRootElement, fMsgNameResolver);
         messages = new Message[] {part};
      }

      importMessages(messages, m_targetDir);
   }

   /**
    * Writes Message metadata to files in the given directory.
    *
    * @param messages The Messages to write.
    * @param targetDir The directory in which the message files will be created.
    * @throws IOException If an error occurs.
    */
   private void importMessages(Message[] messages, File targetDir) throws IOException
   {
      for (int i = 0; i < messages.length; ++i)
      {
         Message msg = messages[i];
         String sFileName = msg.getName() + ".message";
         File newFile = new File(targetDir, sFileName);

         if (newFile.exists())
         {
            int nSeqNumber = 0;

            do
            {
               ++nSeqNumber;
               sFileName = msg.getName() + nSeqNumber + ".message";
               newFile = new File(targetDir, sFileName);
            }
            while (newFile.exists());
         }

         StringWriter sw = new StringWriter();
         XMLMetadataExporter exporter = new XMLMetadataExporter(sw);
         Writer writer = null;
        
         try
         {
            exporter.exportMessage(msg);
           
            String sContents = sw.toString();

            sw = null;
            sContents = XMLUtil.formatXML(sContents);
            writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(newFile)), XMLUtil.ENCODING);
            writer.write(sContents);
         }
         finally
         {
            if (writer != null)
            {
               writer.close();
            }
         }
      }
   }

   /**
    * @see nexj.core.tools.GenericTool#getOptionUsage()
    */
   protected String[] getOptionUsage()
   {
      return new String[]
      {
         "-Dnexj.meta.url=<repository path>",
         "-Dxsd.file=<XSD file path>",
         "-Dwsdl.file=<WSDL file path, use instead of xsd.file to get WSDL output>",
         "-Dwsdl.host=<endpoint host.domain.ext:port>",
         "-Dwsdl.httpRoot=<endpoing http context root path>",
         "-Dout.dir=<output directory>",
         "-Dmsg.prefix=<message prefix>",
      };
   }

   /**
    * @see nexj.core.tools.GenericTool#getCommandUsage()
    */
   protected String[] getCommandUsage()
   {
      return new String[]
      {
         "import ...  - import message(s). Followed by optional root level elements to process.",
         "export ...  - export message(s). Followed by the messages to export.",
         "exportchannel ... - export channel(s). Followed by the channels to export.",
         "exportinterface ... - export interface(s). Followed by the interfaces to export."
      };
   }

   public static void main(String[] args)
   {
      new XSDMessageTool().run(args);
   }
}
TOP

Related Classes of nexj.core.tools.XSDMessageTool

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.