<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- Generated by Apache Maven Doxia at 2018-01-20 -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Apache Chainsaw &#x2013; CPD Results</title>
    <style type="text/css" media="all">
      @import url("./css/maven-base.css");
      @import url("./css/maven-theme.css");
      @import url("./css/site.css");
    </style>
    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
    <meta name="Date-Revision-yyyymmdd" content="20180120" />
    <meta http-equiv="Content-Language" content="en" />
        
        </head>
  <body class="composite">
    <div id="banner">
                        <a href="http://logging.apache.org/" id="bannerLeft">
                                                <img src="images/ls-logo.jpg" alt="Logging Services" />
                </a>
                              <a href="http://logging.apache.org/log4j" id="bannerRight">
                                                <img src="images/logo.jpg" alt="Apache log4j" />
                </a>
            <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="breadcrumbs">
            
                
                <div class="xleft">
        <span id="publishDate">Last Published: 2018-01-20</span>
                  &nbsp;| <span id="projectVersion">Version: 2.0.0</span>
                          |                           <a href="http://www.apache.org/" class="externalLink" title="Apache">Apache</a>
        &gt;
                          <a href="http://logging.apache.org/" class="externalLink" title="Logging Services">Logging Services</a>
        &gt;
                          <a href="http://logging.apache.org:80/chainsaw/" class="externalLink" title="Chainsaw">Chainsaw</a>
        &gt;
    Apache Chainsaw &#x2013; CPD Results
              </div>
            <div class="xright">        
                
      </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="leftColumn">
      <div id="navcolumn">
             
                
                                <h5>Get Chainsaw</h5>
                  <ul>
                  <li class="none">
                          <a href="download.html" title="Download">Download</a>
            </li>
                  <li class="none">
                          <a href="changes-report.html" title="Changes">Changes</a>
            </li>
                  <li class="none">
                          <a href="http://www.apache.org/licenses/" class="externalLink" title="License">License</a>
            </li>
                  <li class="none">
                          <a href="distributionnotes.html" title="Important Distribution Notes">Important Distribution Notes</a>
            </li>
          </ul>
                       <h5>About Chainsaw</h5>
                  <ul>
                  <li class="none">
                          <a href="index.html" title="Introduction">Introduction</a>
            </li>
                  <li class="none">
                          <a href="quicktour.html" title="Quick Tour">Quick Tour</a>
            </li>
                  <li class="none">
                          <a href="zeroconf.html" title="Zeroconf">Zeroconf</a>
            </li>
                  <li class="none">
                          <a href="roadmap.html" title="Roadmap">Roadmap</a>
            </li>
                  <li class="none">
                          <a href="apidocs/index.html" title="JavaDoc">JavaDoc</a>
            </li>
          </ul>
                       <h5>Community</h5>
                  <ul>
                  <li class="none">
                          <a href="mail-lists.html" title="Mailing Lists">Mailing Lists</a>
            </li>
                  <li class="none">
                          <a href="issue-tracking.html" title="Issue Tracking">Issue Tracking</a>
            </li>
          </ul>
                       <h5>Development</h5>
                  <ul>
                  <li class="none">
                          <a href="source-repository.html" title="Repository">Repository</a>
            </li>
                  <li class="none">
                          <a href="xref/index.html" title="Cross Reference">Cross Reference</a>
            </li>
                  <li class="none">
                          <a href="dependencies.html" title="Dependencies">Dependencies</a>
            </li>
                  <li class="none">
            <strong>Duplication</strong>
          </li>
                  <li class="none">
                          <a href="pmd.html" title="PMD">PMD</a>
            </li>
          </ul>
                       <h5>Apache</h5>
                  <ul>
                  <li class="none">
                          <a href="http://www.apache.org" class="externalLink" title="Home">Home</a>
            </li>
                  <li class="none">
                          <a href="http://www.apache.org/foundation/sponsorship.html" class="externalLink" title="Sponsorship">Sponsorship</a>
            </li>
                  <li class="none">
                          <a href="http://www.apache.org/foundation/thanks.html" class="externalLink" title="Thanks">Thanks</a>
            </li>
                  <li class="none">
                          <a href="https://www.apache.org/security/" class="externalLink" title="Security">Security</a>
            </li>
                  <li class="none">
                          <a href="http://www.apachecon.com" class="externalLink" title="Conferences">Conferences</a>
            </li>
          </ul>
                             <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
      </a>
                   
                
            </div>
    </div>
    <div id="bodyColumn">
      <div id="contentBox">
        <div class="section">
<h2><a name="CPD_Results"></a>CPD Results</h2>
<p>The following document contains the results of PMD's  <a class="externalLink" href="http://pmd.sourceforge.net/cpd.html">CPD</a> 5.6.1.</p></div>
<div class="section">
<h2><a name="Duplications"></a>Duplications</h2>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/xml/UtilLoggingXMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/UtilLoggingXMLDecoder.html#L167">167</a></td></tr>
<tr class="a">
<td>org/apache/log4j/xml/XMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/XMLDecoder.html#L171">171</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>      InputSource inputSource =
        new InputSource(new StringReader(buf.toString()));
      document = docBuilder.parse(inputSource);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return document;
  }

  /**
   * Decodes a File into a Vector of LoggingEvents.
   * @param url the url of a file containing events to decode
   * @return Vector of LoggingEvents
   * @throws IOException if IO error during processing.
   */
  public Vector decode(final URL url) throws IOException {
    LineNumberReader reader;
    boolean isZipFile = url.getPath().toLowerCase().endsWith(&quot;.zip&quot;);
    InputStream inputStream;
    if (isZipFile) {
        inputStream = new ZipInputStream(url.openStream());
        //move stream to next entry so we can read it
        ((ZipInputStream)inputStream).getNextEntry();
    } else {
        inputStream = url.openStream();
    }
    if (owner != null) {
        reader = new LineNumberReader(
                new InputStreamReader(
                        new ProgressMonitorInputStream(owner,
                                &quot;Loading &quot; + url , inputStream), ENCODING));
    } else {
        reader = new LineNumberReader(new InputStreamReader(inputStream, ENCODING));
    }
    Vector v = new Vector();

      String line;
      Vector events;
      try {
          while ((line = reader.readLine()) != null) {
              StringBuffer buffer = new StringBuffer(line);
              for (int i = 0; i &lt; 1000; i++) {
                  buffer.append(reader.readLine()).append(&quot;\n&quot;);
              }
              events = decodeEvents(buffer.toString());
              if (events != null) {
                  v.addAll(events);
              }
          }
    } finally {
      partialEvent = null;
      try {
        if (reader != null) {
          reader.close();
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return v;
  }

  /**
   * Decodes a String representing a number of events into a
   * Vector of LoggingEvents.
   * @param document to decode events from
   * @return Vector of LoggingEvents
   */
  public Vector decodeEvents(final String document) {

      if (document != null) {

          if (document.trim().equals(&quot;&quot;)) {
              return null;
          }

          String newDoc;</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/xml/UtilLoggingXMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/UtilLoggingXMLDecoder.html#L245">245</a></td></tr>
<tr class="a">
<td>org/apache/log4j/xml/XMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/XMLDecoder.html#L247">247</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>          String newPartialEvent = null;
          //separate the string into the last portion ending with &lt;/record&gt;
          // (which will be processed) and the partial event which
          // will be combined and processed in the next section

          //if the document does not contain a record end,
          // append it to the partial event string
          if (document.lastIndexOf(RECORD_END) == -1) {
              partialEvent = partialEvent + document;
              return null;
          }

          if (document.lastIndexOf(RECORD_END) + RECORD_END.length()
                  &lt; document.length()) {
              newDoc = document.substring(0,
                      document.lastIndexOf(RECORD_END) + RECORD_END.length());
              newPartialEvent = document.substring(
                      document.lastIndexOf(RECORD_END) + RECORD_END.length());
          } else {
              newDoc = document;
          }
          if (partialEvent != null) {
              newDoc = partialEvent + newDoc;
          }
          partialEvent = newPartialEvent;

          Document doc = parse(newDoc);
          if (doc == null) {
              return null;
          }
          return decodeEvents(doc);
      }
      return null;
  }

    /**
      * Converts the string data into an XML Document, and then soaks out the
      * relevant bits to form a new LoggingEvent instance which can be used
      * by any Log4j element locally.
      * @param data XML fragment
      * @return a single LoggingEvent or null
      */
  public LoggingEvent decode(final String data) {
    Document document = parse(data);

    if (document == null) {
      return null;
    }

    Vector events = decodeEvents(document);

    if (events.size() &gt; 0) {
      return (LoggingEvent) events.firstElement();
    }

    return null;
  }

  /**
   * Given a Document, converts the XML into a Vector of LoggingEvents.
   * @param document XML document
   * @return Vector of LoggingEvents
   */
  private Vector decodeEvents(final Document document) {
    Vector events = new Vector();</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/chainsaw/icons/LineIconFactory.java</td>
<td><a href="./xref/org/apache/log4j/chainsaw/icons/LineIconFactory.html#L51">51</a></td></tr>
<tr class="a">
<td>org/apache/log4j/chainsaw/icons/LineIconFactory.java</td>
<td><a href="./xref/org/apache/log4j/chainsaw/icons/LineIconFactory.html#L83">83</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>  public static Icon createExpandIcon() {
      int size = 8;
      int xOffSet = 0;
      int yOffSet = 0;
    try {
      GraphicsEnvironment environment =
        GraphicsEnvironment.getLocalGraphicsEnvironment();
        BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2D =
        environment.createGraphics(
          image);
        g2D.setBackground(new Color(0,0,0,0));
        g2D.clearRect(0,0,size,size);
        g2D.setStroke(new BasicStroke(1.5f));
        g2D.setRenderingHint(
          RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        g2D.setColor(Color.black);
        g2D.drawLine(
           xOffSet, (size / 2) + yOffSet, size - xOffSet,
           (size / 2) + yOffSet);</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/chainsaw/LogPanel.java</td>
<td><a href="./xref/org/apache/log4j/chainsaw/LogPanel.html#L3884">3884</a></td></tr>
<tr class="a">
<td>org/apache/log4j/chainsaw/LogPanel.java</td>
<td><a href="./xref/org/apache/log4j/chainsaw/LogPanel.html#L3960">3960</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>                i++;
                //only add if there is a color defined
                if (primaryMatches(wrapper)) {
                    primaryList.add(wrapper);
                }
            }
            revalidate();
            repaint();
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            int rowCount = table.getRowCount();
            if (rowCount == 0) {
                return;
            }
            //use event pane height as reference height - max component height will be extended by event height if
            // last row is rendered, so subtract here
            int height = eventsPane.getHeight();
            int maxHeight = Math.min(maxEventHeight, (height / rowCount));
            int minHeight = Math.max(1, maxHeight);
            int componentHeight = height - minHeight;
            int eventHeight = minHeight;

            //draw all events
            for (Iterator iter = primaryList.iterator();iter.hasNext();) {
                ThumbnailLoggingEventWrapper wrapper = (ThumbnailLoggingEventWrapper)iter.next();
                    if (primaryMatches(wrapper)) {</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/net/MulticastAppender.java</td>
<td><a href="./xref/org/apache/log4j/net/MulticastAppender.html#L86">86</a></td></tr>
<tr class="a">
<td>org/apache/log4j/net/UDPAppender.java</td>
<td><a href="./xref/org/apache/log4j/net/UDPAppender.html#L105">105</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>     super(false);
  }

  /**
     Open the multicast sender for the &lt;b&gt;RemoteHost&lt;/b&gt; and &lt;b&gt;Port&lt;/b&gt;.
  */
  public void activateOptions() {
    try {
      hostname = InetAddress.getLocalHost().getHostName();
    } catch (UnknownHostException uhe) {
      try {
        hostname = InetAddress.getLocalHost().getHostAddress();
      } catch (UnknownHostException uhe2) {
        hostname = &quot;unknown&quot;;
      }
    }

    //allow system property of application to be primary
    if (application == null) {
      application = System.getProperty(Constants.APPLICATION_KEY);
    } else {
      if (System.getProperty(Constants.APPLICATION_KEY) != null) {
        application = application + &quot;-&quot; + System.getProperty(Constants.APPLICATION_KEY);
      }
    }

    if(remoteHost != null) {
      address = getAddressByName(remoteHost);</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/xml/XMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/XMLDecoder.html#L363">363</a></td></tr>
<tr class="a">
<td>org/apache/log4j/xml/XMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/XMLDecoder.html#L403">403</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>          NodeList propertyList = list.item(y).getChildNodes();
          int propertyLength = propertyList.getLength();

          for (int i = 0; i &lt; propertyLength; i++) {
            String propertyTag = propertyList.item(i).getNodeName();

            if (propertyTag.equalsIgnoreCase(&quot;log4j:data&quot;)) {
              Node property = propertyList.item(i);
              String name =
                property.getAttributes().getNamedItem(&quot;name&quot;).getNodeValue();
              String value =
                property.getAttributes().getNamedItem(&quot;value&quot;).getNodeValue();
              properties.put(name, value);
            }
          }
        }

        if (tagName.equalsIgnoreCase(&quot;log4j:throwable&quot;)) {</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/chainsaw/LogPanel.java</td>
<td><a href="./xref/org/apache/log4j/chainsaw/LogPanel.html#L4109">4109</a></td></tr>
<tr class="a">
<td>org/apache/log4j/chainsaw/LogPanel.java</td>
<td><a href="./xref/org/apache/log4j/chainsaw/LogPanel.html#L4129">4129</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>                    } else if (e.getType() == TableModelEvent.DELETE) {
                        //find each eventwrapper with an id in the deleted range and remove it...
//                        System.out.println(&quot;delete- current warnings: &quot; + warnings.size() + &quot;, errors: &quot; + errors.size() + &quot;, first row: &quot; + firstRow + &quot;, last row: &quot; + lastRow + &quot;, displayed event count: &quot; + displayedEvents.size() );
                        for (Iterator iter = secondaryList.iterator();iter.hasNext();) {
                            ThumbnailLoggingEventWrapper wrapper = (ThumbnailLoggingEventWrapper)iter.next();
                            if ((wrapper.rowNum &gt;= firstRow) &amp;&amp; (wrapper.rowNum &lt;= lastRow)) {
//                                System.out.println(&quot;deleting find: &quot; + wrapper);
                                iter.remove();
                            }
                        }
                        for (Iterator iter = primaryList.iterator();iter.hasNext();) {
                            ThumbnailLoggingEventWrapper wrapper = (ThumbnailLoggingEventWrapper)iter.next();
                            if ((wrapper.rowNum &gt;= firstRow) &amp;&amp; (wrapper.rowNum &lt;= lastRow)) {
//                                System.out.println(&quot;deleting error: &quot; + wrapper);
                                iter.remove();
                            }
                        }</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/xml/UtilLoggingXMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/UtilLoggingXMLDecoder.html#L415">415</a></td></tr>
<tr class="a">
<td>org/apache/log4j/xml/XMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/XMLDecoder.html#L433">433</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>            }
        }

      LocationInfo info;
      if ((fileName != null)
              || (className != null)
              || (methodName != null)
              || (lineNumber != null)) {
          info = new LocationInfo(fileName, className, methodName, lineNumber);
      } else {
        info = LocationInfo.NA_LOCATION_INFO;
      }

        ThrowableInformation throwableInfo = null;
        if (exception != null) {
            throwableInfo = new ThrowableInformation(exception);
        }

        LoggingEvent loggingEvent = new LoggingEvent(null,
                logger, timeStamp, level, message,
                threadName,
                throwableInfo,
                ndc,
                info,
                properties);

      events.add(loggingEvent);</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/xml/UtilLoggingXMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/UtilLoggingXMLDecoder.html#L443">443</a></td></tr>
<tr class="a">
<td>org/apache/log4j/xml/XMLDecoder.java</td>
<td><a href="./xref/org/apache/log4j/xml/XMLDecoder.html#L469">469</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>    }
    return events;
  }

    /**
     * Get contents of CDATASection.
     * @param n CDATASection
     * @return text content of all text or CDATA children of node.
     */
  private String getCData(final Node n) {
    StringBuffer buf = new StringBuffer();
    NodeList nl = n.getChildNodes();

    for (int x = 0; x &lt; nl.getLength(); x++) {
      Node innerNode = nl.item(x);

      if (
        (innerNode.getNodeType() == Node.TEXT_NODE)
          || (innerNode.getNodeType() == Node.CDATA_SECTION_NODE)) {
        buf.append(innerNode.getNodeValue());
      }
    }

    return buf.toString();
  }
}</pre></div></td></tr></table>
<table border="0" class="bodyTable">
<tr class="a">
<th>File</th>
<th>Line</th></tr>
<tr class="b">
<td>org/apache/log4j/net/SocketNode13.java</td>
<td><a href="./xref/org/apache/log4j/net/SocketNode13.html#L201">201</a></td></tr>
<tr class="a">
<td>org/apache/log4j/net/XMLSocketNode.java</td>
<td><a href="./xref/org/apache/log4j/net/XMLSocketNode.html#L172">172</a></td></tr>
<tr class="b"><td colspan='2'>
<div>
<pre>          }
        }
      } catch (java.io.EOFException e) {
        getLogger().info(&quot;Caught java.io.EOFException closing connection.&quot;);
        listenerException = e;
      } catch (java.net.SocketException e) {
        getLogger().info(&quot;Caught java.net.SocketException closing connection.&quot;);
        listenerException = e;
      } catch (IOException e) {
        getLogger().info(&quot;Caught java.io.IOException: &quot; + e);
        getLogger().info(&quot;Closing connection.&quot;);
        listenerException = e;
      } catch (Exception e) {
        getLogger().error(&quot;Unexpected exception. Closing connection.&quot;, e);
        listenerException = e;
      }
    }

    // close the socket
    try {
      if (ois != null) {</pre></div></td></tr></table></div>
      </div>
    </div>
    <div class="clear">
      <hr/>
    </div>
    <div id="footer">
      <div>
        <div class="center">Copyright &#169;                    2002-2018
                        <a href="https://www.apache.org">Apache Software Foundation</a>.
                  
                
       Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License, Version 2.0</a>.</div><br />
        <div class="center">Apache Logging, Apache Log4j, Log4j, Apache Chainsaw, Chainsaw, Apache, the Apache feather logo, the Apache Logging project logo,
          and the Apache Log4j logo are trademarks of The Apache Software Foundation.</div>
      </div>
    </div>
  </body>
</html>
