All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.squirrel_sql.fw.datasetviewer.XmlRefomatter Maven / Gradle / Ivy

Go to download

The framework library contains utility classes that are generic and useful for building applications that introspect a database via JDBC. These are not intended to be SQuirreLSQL-specific and could be used by other projects JDBC front-end applications. This project is guaranteed to have no code dependencies on other SQuirreLSQL projects and could therefore be used when building a different JDBC front-end application.

There is a newer version: 3.5.0
Show newest version
package net.sourceforge.squirrel_sql.fw.datasetviewer;
/*
 * Copyright (C) 2004 Gerd Wagner
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 import net.sourceforge.squirrel_sql.fw.util.StringManager;
 import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;

 import javax.swing.JOptionPane;
 import java.util.ArrayList;

/**
 * This is an XML prettyprinter.  It takes a string that is in XML format
 * and converts it into a multi-line, indented structure
 * that is easier for the user to read.
 * Prior to calling this method, nothing in Squirrel is "XML-aware",
 * so we do not prevent the user from calling this method if the
 * data is not an XML string.
 * However, we do warn the user if the data is not XML or is improperly formatted.
 */
public class XmlRefomatter
{

	private static final StringManager s_stringMgr =
		StringManagerFactory.getStringManager(XmlRefomatter.class);


	// i18n[xmlRefomatter.unexpectedProblem=Unexpected problem during formatting.]
	private static String DEFAULT_MESSAGE = s_stringMgr.getString("xmlRefomatter.unexpectedProblem");
	private static String _message = DEFAULT_MESSAGE;
   private static boolean _showWarningMessages = true;

   public static String reformatXml(String xml)
	{
		// do a simple check to see if the string might contain XML or not
		if (xml.indexOf("<") == -1 || xml.equals("")) {
			// no tags, so cannot be XML
			JOptionPane.showMessageDialog(null,
				// i18n[xmlRefomatter.noXml=The data does not contain any XML tags.  No reformatting done.]
				s_stringMgr.getString("xmlRefomatter.noXml"),
				// i18n[xmlRefomatter.xmlWarning=XML Warning]
				s_stringMgr.getString("xmlRefomatter.xmlWarning"), JOptionPane.WARNING_MESSAGE);
			return xml;
		}

		try
		{
			StringBuffer ret = new StringBuffer();
			int depth = 0;
			ParseRes parseRes = getParseRes(xml, 0);

			if (parseRes == null)
         {
				// the parse did not find XML, or it was mal-formed
            showWarning(_message);
				return xml;
			}

			xml = xml.trim();

			// GWG XML format check code
			ArrayList tagList = new ArrayList();	

			while(null != parseRes)
			{

				if(ParseRes.BEGIN_TAG == parseRes.type)
				{
					tagList.add(parseRes.item);	// GWG XML format check code

					ret.append(getIndent(depth)).append(parseRes.item);
					ParseRes nextRes = getParseRes(xml, parseRes.pos);

					// see if there was a problem during parsing
					if (nextRes == null) {
						// the parse did not find XML, or it was mal-formed
					    showWarning(_message);
						return xml;
					}

					if(ParseRes.TEXT != nextRes.type)
					{
						ret.append("\n");
					}

					++depth;
				}
				else if(ParseRes.END_TAG == parseRes.type)
				{
					// GWG format check code follows...
					if (tagList.size()> 0 ) {
						String startTag = tagList.remove(tagList.size()-1);
						// Assume that all start tags are "<...>" or include a space
						// after the tag name (e.g. as in "" and all
						// end tags are "".  Remove the syntactic markers,
						// then remove any spaces, and convert to upper case for comparison
						String testableStartTag = startTag.substring(1, startTag.length() -1).trim().toUpperCase();
						if (testableStartTag.indexOf(' ') > -1)
							testableStartTag = testableStartTag.substring(0, testableStartTag.indexOf(' '));
						String endTag = parseRes.item.substring(2, parseRes.item.length()-1).trim().toUpperCase();

						if ( ! testableStartTag.equals(endTag))
                  {
							Object[] args = new Object[]{startTag, parseRes.item};

							// i18n[xmlRefomatter.malformedXml=Possible mal-formed XML:\n   Starting tag was: {0}\nEnding Tag was: {1}\nContinuing with reformatting XML."]
							String msg = s_stringMgr.getString("xmlRefomatter.malformedXml", args);
							showWarning(msg);
						}
					}
					// End GWG format check code

					--depth;
					if(ret.toString().endsWith("\n"))
					{
						ret.append(getIndent(depth));
					}
					ret.append(parseRes.item).append("\n");
				}
				else if(ParseRes.CLOSED_TAG == parseRes.type)
				{
					ret.append(getIndent(depth)).append(parseRes.item).append("\n");
				}
				else if(ParseRes.TEXT == parseRes.type)
				{
					ret.append(parseRes.item);
				}
				parseRes = getParseRes(xml, parseRes.pos);
			}

			return ret.toString();
		}
		catch(Exception e)
		{
			// the parse did not find XML, or it was mal-formed
			JOptionPane.showMessageDialog(null,
				DEFAULT_MESSAGE,
				// i18n[xmlReformatter.xmlWarning2=XML Warning]
				s_stringMgr.getString("xmlReformatter.xmlWarning2"), JOptionPane.WARNING_MESSAGE);
			e.printStackTrace();
		}
      finally
      {
         _message = DEFAULT_MESSAGE;
         _showWarningMessages = true;
      }
		return xml;

	}


   private static void showWarning(String message)
   {
      if(false == _showWarningMessages)
      {
         return;
      }

      Object[] options =
			{
				// i18n[xmlReformatter.yes=YES]
				s_stringMgr.getString("xmlReformatter.yes"),
				// i18n[xmlReformatter.no=NO]
				s_stringMgr.getString("xmlReformatter.no")
			};


		int ret = JOptionPane.showOptionDialog(null,
		    		 // i18n[xmlReformatter.seeOtherErrs={0}\nDo you wish to see other errors?"]
					s_stringMgr.getString("xmlReformatter.seeOtherErrs", message),
					 // i18n[xmlReformatter.xmlWarning5=XML Warning]
                s_stringMgr.getString("xmlReformatter.xmlWarning5"),
                JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
                null, options, options[0]);


      if(0 != ret)
      {
         _showWarningMessages = false;
      }

   }


	private static ParseRes getParseRes(String xml, int pos)
	{
		if(pos >= xml.length())
		{
			return null;
		}

		pos = moveOverWhiteSpaces(xml, pos);

		int ltIndex = xml.indexOf("<", pos);
		int gtIndex = xml.indexOf(">", pos);

		ParseRes ret = new ParseRes();

		if(pos == ltIndex)
		{
			ret.item = xml.substring(ltIndex, gtIndex+1);

			if(xml.length() > ltIndex+1 && xml.charAt(ltIndex+1) == '/')
			{
				ret.type = ParseRes.END_TAG;
			}
			else if(pos < gtIndex-1 && xml.charAt(gtIndex-1) == '/')
			{
				ret.type = ParseRes.CLOSED_TAG;
			}
			else
			{
				ret.type = ParseRes.BEGIN_TAG;
			}
			ret.pos = gtIndex+1;
		}
		else
		{
			//			check for "malformed" XML, or text that happens to contain
			//			a "<" with no corresponding ">"
			if (ltIndex == -1) {
				int lengthToPrint = xml.length() - pos;
				if (lengthToPrint > 40)
					lengthToPrint = 40;

				// i18n[xmlReformatter.malformedXmlAt=Malformed XML.  No ending tag seen for text starting at:\n{0}]
				_message = s_stringMgr.getString("xmlReformatter.malformedXmlAt", xml.substring(pos, pos + lengthToPrint));
				return null;
			}		

			ret.type = ParseRes.TEXT;
			ret.item = xml.substring(pos, ltIndex);
			ret.pos = ltIndex;
		}

		return ret;
	}

	private static int moveOverWhiteSpaces(String xml, int pos)
	{
		int ret = pos;

		while(Character.isWhitespace(xml.charAt(ret)))
		{
			++ret;
		}
		return ret;

	}

	private static String getIndent(int depth)
	{
		StringBuffer ret = new StringBuffer("");
		for(int i=0; i < depth; ++i)
		{
			ret.append("   ");
		}
		return ret.toString();
	}

	static class ParseRes
	{
		public static final int BEGIN_TAG = 0;
		public static final int END_TAG = 1;
		public static final int CLOSED_TAG = 2;
		public static final int TEXT = 3;

		String item;
		int type;
		int pos;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy