⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmleditor.java

📁 一个完整的XACML工程,学习XACML技术的好例子!
💻 JAVA
字号:
/*
* Copyright (c) 2006, University of Kent
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this 
* list of conditions and the following disclaimer.
* 
* Redistributions in binary form must reproduce the above copyright notice, 
* this list of conditions and the following disclaimer in the documentation 
* and/or other materials provided with the distribution. 
*
* 1. Neither the name of the University of Kent nor the names of its 
* contributors may be used to endorse or promote products derived from this 
* software without specific prior written permission. 
*
* 2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS  
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE ARE DISCLAIMED. 
*
* 3. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
* POSSIBILITY OF SUCH DAMAGE.
*
* 4. YOU AGREE THAT THE EXCLUSIONS IN PARAGRAPHS 2 AND 3 ABOVE ARE REASONABLE
* IN THE CIRCUMSTANCES.  IN PARTICULAR, YOU ACKNOWLEDGE (1) THAT THIS
* SOFTWARE HAS BEEN MADE AVAILABLE TO YOU FREE OF CHARGE, (2) THAT THIS
* SOFTWARE IS NOT "PRODUCT" QUALITY, BUT HAS BEEN PRODUCED BY A RESEARCH
* GROUP WHO DESIRE TO MAKE THIS SOFTWARE FREELY AVAILABLE TO PEOPLE WHO WISH
* TO USE IT, AND (3) THAT BECAUSE THIS SOFTWARE IS NOT OF "PRODUCT" QUALITY
* IT IS INEVITABLE THAT THERE WILL BE BUGS AND ERRORS, AND POSSIBLY MORE
* SERIOUS FAULTS, IN THIS SOFTWARE.
*
* 5. This license is governed, except to the extent that local laws
* necessarily apply, by the laws of England and Wales.
*/

/*
 * XMLEditor.java - 18/01/2006
 */

package issrg.utils.xml;

import javax.swing.JPanel;
import javax.swing.event.EventListenerList;
import java.util.*;
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.stream.*;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xml.serialize.LineSeparator;
import org.w3c.dom.*;
import org.xml.sax.*;

/**
 * An Abstract class, that handles core XML editing functions.
 *
 * @author Christian Azzopardi
 */
public abstract class XMLEditor extends JPanel
{   
    /**
     * Flag that is used to notify if there is any event on the undo Stack
     */
    public boolean canUndo = false;
    
    /**
     * Flag that is used to notify if there is any event on the redo Stack
     */
    public boolean canRedo = false;
    
    /**
     * Stack that keeps a list of items that can be undone
     */
    public Stack done = new Stack();

    /**
     * Stack that keeps a list of items that can be redone
     */    
    public Stack undone = new Stack();   
    
    /**
     * org.w3c.dom.Document where the elements are stored
     */
    public Document DOM;
    
    /**
     * Root element of the Document DOM
     */
    Element root;
    
    public PolicyValidator policyValidator;
    
    /** Creates a new instance of XMLEditor */
    public XMLEditor() 
    {
    }
    
   /**
    * A list of components registered as XML Change Listeners
    */
   EventListenerList XMLChangeListeners = new EventListenerList();

   /**
    * Method to add a listener to any XML Change 
    *
    * @param listener   the component that listens to XML Changes to be added to
    *                   the listener list.
    */ 
   public void addXMLChangeListener(XMLChangeListener listener)
   {
      XMLChangeListeners.add(XMLChangeListener.class, listener);
   }

   /**
    * Method to remove a listener to any XML Change 
    *
    * @param listener   the component to be removed from the listener list
    */ 
   public void removeXMLChangeListener(XMLChangeListener listener)
   {
      XMLChangeListeners.remove(XMLChangeListener.class, listener);
   }
   
   /**
    *  Constructs the XMLChangeEvent to Modify the Element's Attributes with the
    *  list of their respective values. 
    *
    *  @param parent    The Element to modify
    *  @param attribs   A String Array of attributes to modify
    *  @param values    The corresponding values of the attributes to set
    */
   public void setAttributeValue(Element parent, String attribs[], String values[])
   {
       String oldValues[] = new String[attribs.length];
       for (int i = 0; i < parent.getAttributes().getLength(); i++)
       {
           oldValues[i] = parent.getAttribute(attribs[i]);
       }
       XMLChangeEvent xmle = new XMLChangeEvent(this, parent, attribs, values, oldValues, "NODE_MODIFIED");
       canRedo = false;
       undone.clear();
       doEvent(xmle);
   }
   
   public void replaceNode(Element parent, Element oldChild, Element newChild)
   {
      XMLChangeEvent xmle = new XMLChangeEvent(this, parent, oldChild, newChild, "NODE_REPLACED");
      canRedo = false; 
      undone.clear();
      doEvent(xmle);       
   }
   
   /**
    *  Method that undoes the last performed action stored on the done stack.
    *  This last performed action is taken off the done stack and stored in 
    *  the undone stack to be able to redo.
    */
   public void undo()
   {
      if (done.empty()) return ;
      XMLChangeEvent ev = (XMLChangeEvent)done.pop();
      undone.push(ev);
      canRedo=true;
      processEvent(not(ev));
   }

   /**
    *  Method that redoes the first XMLChangeEvent that is on the undone Stack.
    *  This last performed redo action is then taken off the undone stack.
    */
   public void redo()
   {
      if (undone.empty()) return;
      XMLChangeEvent ev = (XMLChangeEvent)undone.pop();
      doEvent(ev);
   }

   /**
    *  Method that fires XMLChanged notifications to a list of registered
    *  listeners.
    */
   public void notifyChanges(XMLChangeEvent ev)
   {
      EventListener[] listeners = XMLChangeListeners.getListeners(XMLChangeListener.class);
      for(int i = 0; i < listeners.length ; i++)
      {
         ((issrg.utils.xml.XMLChangeListener)listeners[i]).XMLChanged(ev);
      }
   }
   
   /**
    *  Initializes the done Stack.
    */
   public void newDoneStack()
   {
       this.done = new Stack();
   }
   
   /**
    *  Initializes the undone Stack.
    */
   public void newUnDoneStack()
   {
       this.undone = new Stack();
   }

   /**
    *  This method will identify what type of XMLChangedEvent
    *  has just been fired, and act upon it. This can have one of 
    *  four forms that will be passed with the XMLChangeEvent:
    *  NODE_ADDED    - when a node is being added to XML.
    *  NODE_DELETED  - when a node is being deleted to XML.
    *  NODE_MODIFIED - when a node is being changed from the XML.
    *  NEW_XML       - when a new policy is created.
    *  <p>
    *  It will then call notifyChanges, to notify any registered listeners 
    *  with the changes.
    */
   public void processEvent(XMLChangeEvent ev)
   {
      //request focus on any XML changed event to help with undo/redo...
      
      if(ev.getAction() == "NODE_ADDED")
      {
          int pos = ev.getChildIndex();
          if (pos >= ev.getParentNode().getChildNodes().getLength())
          {
            ev.getParentNode().appendChild(ev.getChildNode());
          }
          else
          {
              NodeList nl = ev.getParentNode().getChildNodes();
              
              ev.getParentNode().insertBefore(ev.getChildNode(), nl.item(pos));
          }
      }
      else if(ev.getAction() == "NODE_DELETED")
      {
         ev.getParentNode().removeChild(ev.getChildNode()); 
      }
      else if(ev.getAction() == "NODE_MODIFIED")
      {
          for (int i = 0; i < ev.getAttributeNames().length; i++)
          {
              ev.getChildNode().setAttribute(ev.getAttributeNames()[i], ev.getAttributeValues()[i]);
          }
      }
      else if(ev.getAction() == "NODE_REPLACED")
      {
         ev.getParentNode().replaceChild(ev.getNewChildNode(), ev.getChildNode());
      }
      else if(ev.getAction() == "NEW_XML")
      {
      }
      
      notifyChanges(ev);
   }
   
   /**
    * Obtains the converse of an XMLChangeEvent. This is used in cases were we
    * need to undo/redo. The XMLChangeEvent is popped out of the stack, and the
    * converse is needed to do the opposite action.
    * 
    * @param ev  the event needed to convert.
    * @return    the converse XMLChangeEvent.
    */ 
   public XMLChangeEvent not(XMLChangeEvent ev)
   {
       if(ev.getAction() == "NODE_REPLACED") return new XMLChangeEvent(this, ev.getParentNode(), ev.getChildNode(), ev.getNewChildNode(), "NODE_REPLACED");
       if(ev.getAction() == "NODE_MODIFIED") return new XMLChangeEvent(this, ev.getChildNode(), ev.getAttributeNames(), ev.getOldAttribValues(), ev.getAttributeValues(), "NODE_MODIFIED");
       if(ev.getAction() == "NODE_DELETED") return new XMLChangeEvent(this,ev.getChildNode(),ev.getParentNode(),"NODE_ADDED", ev.getChildIndex());
       return new XMLChangeEvent(this,ev.getChildNode(), ev.getParentNode(),"NODE_DELETED", ev.getChildIndex());
   }
  
   /**
    *  Adds the child element to a parent element in XML.
    *
    *  @param childNode     The child element to add
    *  @param parentNode    The parent element to add to
    */
   public void addItem(Element childNode, Element parentNode)
   {
       addItem(childNode, parentNode, parentNode.getChildNodes().getLength());
   }
   
   /**
    *  Adds the child element to a parent element in XML, at a
    *  specified position. Constructs the necessary XMLChangeEvent.
    *
    *  @param childNode     The child element to add
    *  @param parentNode    The parent element to add to
    *  @param childIndex    The child's position in the parent's set of child nodes
    */
   public void addItem(Element childNode, Element parentNode, int childIndex)
   {
      XMLChangeEvent xmle = new XMLChangeEvent(this, childNode, parentNode, "NODE_ADDED", childIndex);
      canRedo = false; 
      undone.clear();
      doEvent(xmle);       
   }

   /**
    *  Deletes a child element from the parent element.
    *  Constructs the necessary XMLChangeEvent.
    *
    *  @param childNode     The child element to delete
    *  @param parentNode    The parent element to delete from
    */
   public void deleteItem(Element childNode, Element parentNode)
   {
      XMLChangeEvent xmle = new XMLChangeEvent(this, childNode, parentNode, "NODE_DELETED");
      canRedo = false;
      undone.clear();
      doEvent(xmle);
   }

   /**
    *  This method adds to the done stack that something has just been
    *  done and calls processEvent with the received XMLChangeEvent
    *
    *  @param ev    The XMLChangeEvent that specifies was is being done.
    */
   protected void doEvent(XMLChangeEvent ev)
   {
       done.push(ev);
       processEvent(ev);
   }

   /**
    *  Generates the XML file, with Serializing. This enables better
    *  readability when opening a policy in a text editor.
    *
    *  @param baos  An output stream (file) to write to.
    */
   public void GenerateXML(OutputStream baos) 
   {
       StreamResult result = null;
       byte strBytes[];
       try
       {
          OutputFormat format = new OutputFormat();
          format.setLineSeparator(LineSeparator.Windows);  // "\n" wouldnt work well..
          format.setIndenting(true);
          XMLSerializer serializer = new XMLSerializer (baos, format);
          serializer.serialize(this.DOM);
       }
       catch (IOException ioe)
       {
       }
   }
   
   /**
    *  Calls the previous overloaded method GenerateXML(OutputStream),
    *  converts the stream into a string, and returns it.
    *  
    *  @return String   The current XML
    */
   public String GenerateXML()
   {
      String strXML;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      GenerateXML(baos);
      strXML = baos.toString();
      return strXML;
   }
   
   /**
    *  Method to open a Document given an XML String input.
    *  This calls CreateDOM(byte bytesDOM[]).
    *
    *  @param xml   This String should contain the XML policy to open
    */
   public void createDOM(String xml)
   {
       byte [] bytes = null;
       if (xml != null) bytes = xml.getBytes();
       
       createDOM(bytes);
   }
   
   /**
    *  Method to open a Document given an XML byte array input.
    *  This calls CreateDOM(InputStream bais).
    *
    *  @param bytesDOM  A byte Array that should contain the XML policy to open
    */
   public void createDOM(byte bytesDOM[])
   {
         ByteArrayInputStream bais = null;
         if (bytesDOM != null) bais = new ByteArrayInputStream(bytesDOM);
         
         createDOM(bais);
   }
   
   /**
    *  Method to open a Document given an XML String input.
    *  This last of 3 overloaded methods has the actual code to verify,
    *  the InputStream with the policyValidator provided.
    *
    *  @param bais   An InputStream containing the XML to open
    */
   public void createDOM(InputStream bais)
   {
      if(bais!=null)
      {
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         try 
         {
            DocumentBuilder builder = factory.newDocumentBuilder();
            this.DOM = builder.parse(bais);
            
            policyValidator.setDocument(DOM);
            policyValidator.validateDocument();
            
            this.root = this.DOM.getDocumentElement();
         }
         catch (SAXException sxe) { }
         catch (ParserConfigurationException pce) { }
         catch (IOException ioe) { }
         catch (SecurityException se) { }
         catch (ValidationException ve) { }    
      }
      else //create a default DOM with a root element
      {
         try
         {
             policyValidator.setDocument(null);
             this.DOM = policyValidator.getValidDocument();
             this.root = DOM.getDocumentElement();
	 }
	 catch(DOMException doe) { }
      }      
      XMLChangeEvent xmle = new XMLChangeEvent(this, "NEW_XML");
      processEvent(xmle);
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -