001/* Generate a web page that contains links for the appropriate copyrights 002 003 Copyright (c) 2003-2018 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 */ 027package ptolemy.actor.gui; 028 029import java.io.File; 030import java.io.IOException; 031import java.net.URL; 032import java.util.Comparator; 033import java.util.HashMap; 034import java.util.HashSet; 035import java.util.Iterator; 036import java.util.Map; 037import java.util.Set; 038import java.util.TreeMap; 039 040import ptolemy.data.ArrayToken; 041import ptolemy.data.RecordToken; 042import ptolemy.data.StringToken; 043import ptolemy.data.expr.Parameter; 044import ptolemy.kernel.attributes.VersionAttribute; 045import ptolemy.kernel.util.StringAttribute; 046import ptolemy.util.ClassUtilities; 047import ptolemy.util.FileUtilities; 048 049/////////////////////////////////////////////////////////////////// 050//// GenerateCopyrights 051 052/** 053 Generate an HTML file that contains links to the appropriate 054 copyrights for entities in the configuration. 055 This class looks for particular classes, and if the class is found 056 in the classpath, then a corresponding html file is included 057 in the list of copyrights. 058 059 @author Christopher Hylands 060 @version $Id$ 061 @since Ptolemy II 2.0 062 @Pt.ProposedRating Red (cxh) 063 @Pt.AcceptedRating Red (cxh) 064 */ 065public class GenerateCopyrights { 066 /////////////////////////////////////////////////////////////////// 067 //// public methods //// 068 069 /** Generate HTML about the copyrights for classes that might 070 * be present in the configuration. This method contains 071 * a list of classes and corresponding copyrights. If 072 * a class in the list is present, then we generate html 073 * that contains a link to the copyright. Note that if the 074 * copyright file need not be present on the local machine, 075 * we generate a link to the copy on the Ptolemy website. 076 * 077 * <p>If the configuration contains an _applicationName attribute 078 * then that attributed is used as the name of the application 079 * in the generated text. If _applicationName is not present, 080 * then the default name is "Ptolemy II". 081 * 082 * <p>If the configuration contains an _applicationCopyright 083 * StringAttribute, then the value of that attributed is used 084 * as the location of the copyright html file. If 085 * _applicationCopyright is not present, then 086 * "ptolemy/configs/doc/copyright.htm" is used. 087 * 088 * <p>If the configuration has a parameter called 089 * _applicationCopyrights that is an array of records where 090 * each element is a record 091 * <pre> 092 * {actor="ptolemy.actor.lib.Foo", copyright="foo.htm"} 093 * </pre> 094 * then we add that actor/copyright pair to the list of potential 095 * copyrights. 096 * 097 * @param configuration The configuration to look for the 098 * _applicationName and _applicationCopyright attributes in. 099 * @return A String containing HTML that describes what 100 * copyrights are used by Entities in the configuration 101 */ 102 public static String generateHTML(Configuration configuration) { 103 // A Map of copyrights, where the key is a URL naming 104 // the copyright and the value is a List of entities 105 // that use that as a copyright. 106 HashMap<String, Set<String>> copyrightsMap = new HashMap<String, Set<String>>(); 107 108 // Add the classnames and copyrights. 109 // Alphabetical by className. 110 _addIfClassPresent(copyrightsMap, "com.cureos.numerics.Cobyla", 111 "com/cureos/jcobyla-license.htm"); 112 113 _addIfClassPresent(copyrightsMap, "com.github.sarxos.webcam.Webcam", 114 "lib/webcam-capture-license.htm"); 115 116 _addIfClassPresent(copyrightsMap, 117 "com.github.ojdcheck.OpenJavaDocCheck", 118 "lib/ojdcheck-license.htm"); 119 120 _addIfClassPresent(copyrightsMap, "com.kitfox.svg.app.beans.SVGIcon", 121 "lib/svgSalamander-license.htm"); 122 123 _addIfClassPresent(copyrightsMap, 124 "com.jhlabs.image.AbstractBufferedImageOp", 125 "com/jhlabs/jhlabs-license.htm"); 126 127 _addIfClassPresent(copyrightsMap, "com.microstar.xml.XmlParser", 128 "com/microstar/xml/aelfred-license.htm"); 129 130 _addIfClassPresent(copyrightsMap, "com.sun.jna.Pointer", 131 "lib/jna-license.htm"); 132 133 _addIfClassPresent(copyrightsMap, "com.sleepycat.db.Environment", 134 "ptdb/lib/db-dbxml-license.htm"); 135 136 _addIfClassPresent(copyrightsMap, 137 "com.google.protobuf.MessageOrBuilder", 138 "lib/protobuf-license.htm"); 139 140 _addIfFilePresent(copyrightsMap, 141 "$CLASSPATH/bin/Vergil.app/Contents/MacOS/universalJavaApplicationStub", 142 "lib/universalJavaApplicationStub-license.html"); 143 144 _addIfFilePresent(copyrightsMap, 145 "$CLASSPATH/bin/CapeCode.app/Contents/MacOS/universalJavaApplicationStub", 146 "lib/universalJavaApplicationStub-license.html"); 147 148 _addIfClassPresent(copyrightsMap, 149 "edu.umich.eecs.april.image.AprilTagFilter", 150 "edu/umich/eecs/april/april-license.htm"); 151 152 _addIfClassPresent(copyrightsMap, 153 "edu.cmu.sphinx.api.LiveSpeechRecognizer", 154 "ptolemy/actor/lib/jjs/modules/speechRecognition/sphinx-license.htm"); 155 156 _addIfClassPresent(copyrightsMap, "g4ltl.SolverUtility", 157 "lib/g4ltl-license.htm"); 158 159 _addIfClassPresent(copyrightsMap, "hla.rti.jlc.RtiFactory", 160 "lib/jcerti-license.htm"); 161 162 _addIfClassPresent(copyrightsMap, "interfaces.util.ChicUI", 163 "lib/chic-license.htm"); 164 165 _addIfClassPresent(copyrightsMap, "io.socket.SocketIO", 166 "lib/socketio-license.htm"); 167 168 _addIfClassPresent(copyrightsMap, "javax.servlet.http.HttpServlet", 169 "lib/javax.servlet-api-license.htm"); 170 171 _addIfClassPresent(copyrightsMap, "jni.GenericJNIActor", 172 "jni/launcher/launcher-copyright.htm"); 173 174 _addIfClassPresent(copyrightsMap, 175 "mescal.domains.mescalPE.kernel.parser", 176 "mescal/configs/doc/cup-copyright.htm"); 177 178 _addIfClassPresent(copyrightsMap, 179 "net.jimblackler.Utils.YieldAdapterIterator", 180 "net/jimblackler/Utils/jimblacklerUtils-license.htm"); 181 182 _addIfClassPresent(copyrightsMap, "oscP5.OscP5", 183 "lib/oscP5-license.htm"); 184 185 // Used by RExpression and RExpression2 actors. 186 _addIfClassPresent(copyrightsMap, 187 "org.apache.commons.lang.StringEscapeUtils", 188 "lib/commons-license.htm"); 189 _addIfClassPresent(copyrightsMap, "org.apache.commons.logging.Log", 190 "lib/commons-license.htm"); 191 192 _addIfClassPresent(copyrightsMap, "org.apache.oltu.oauth2.common.OAuth", 193 "lib/org.apache.oltu.oauth2-license.htm"); 194 195 _addIfClassPresent(copyrightsMap, "org.eclipse.jetty.server.Server", 196 "lib/jetty-all-license.htm"); 197 198 _addIfClassPresent(copyrightsMap, 199 "org.eclipse.paho.client.mqttv3.MqttClient", 200 "lib/org.eclipse.paho.client.mqttv3-license.htm"); 201 202 _addIfClassPresent(copyrightsMap, "org.json.JSONObject", 203 "org/json/json-license.htm"); 204 205 _addIfClassPresent(copyrightsMap, "org.jsoup.parser.Parser", 206 "lib/jsoup-license.htm"); 207 208 _addIfClassPresent(copyrightsMap, "org.mozilla.javascript.Context", 209 "lib/js-license.htm"); 210 211 _addIfClassPresent(copyrightsMap, "org.junit.runner.JUnitCore", 212 "lib/junit-license.htm"); 213 214 _addIfClassPresent(copyrightsMap, 215 "org.netbeans.api.visual.widget.Scene", 216 "lib/netbeans-visual-library-license.htm"); 217 218 _addIfClassPresent(copyrightsMap, "org.ptolemy.fmi.driver.OutputRow", 219 "org/ptolemy/fmi/driver/fmusdk-license.htm"); 220 221 // Used by RExpression2 actor. 222 _addIfClassPresent(copyrightsMap, "org.rosuda.JRI.REXP", 223 "lib/JRI-license.htm"); 224 225 _addIfClassPresent(copyrightsMap, 226 "org.satlive.jsat.objects.ExternalLiteral", 227 "mescal/configs/doc/jsat-copyright.htm"); 228 229 // ant is used by JSAccessor, but we can't have a class have 230 // two licenses associated with it, so we look for 231 // AccessorLibrary and include apache-ant-license.htm 232 _addIfClassPresent(copyrightsMap, 233 "org.terraswarm.accessor.AccessorLibrary", 234 "ant/apache-ant-license.htm"); 235 236 _addIfClassPresent(copyrightsMap, "org.terraswarm.accessor.JSAccessor", 237 "org/terraswarm/accessor/accessors/web/accessors-license.htm"); 238 239 // Vertx 240 _addIfClassPresent(copyrightsMap, 241 "com.fasterxml.jackson.core.base.GeneratorBase", 242 "lib/jackson-license.htm"); 243 244 _addIfClassPresent(copyrightsMap, 245 "io.netty.handler.traffic.ChannelTrafficShapingHandler", 246 "lib/netty-license.htm"); 247 248 _addIfClassPresent(copyrightsMap, 249 "org.vertx.java.spi.cluster.impl.hazelcast.HazelcastAsyncMap", 250 "lib/hazelcast-license.htm"); 251 252 _addIfClassPresent(copyrightsMap, "io.vertx.core.Vertx", 253 "lib/vertx-license.htm"); 254 255 _addIfClassPresent(copyrightsMap, "ptolemy.actor.gui.BrowserLauncher", 256 "ptolemy/actor/gui/BrowserLauncher-license.htm"); 257 _addIfClassPresent(copyrightsMap, 258 "ptolemy.actor.gui.PortConfigurerDialog", 259 "ptolemy/actor/gui/PortConfigurerDialog-license.htm"); 260 _addIfClassPresent(copyrightsMap, 261 "ptolemy.actor.gui.run.PtolemyFormEditor", 262 "com/jgoodies/jgoodies-copyright.htm"); 263 _addIfClassPresent(copyrightsMap, 264 "ptolemy.actor.gui.run.RunLayoutFrame", 265 "org/mlc/mlc-copyright.htm"); 266 _addIfClassPresent(copyrightsMap, 267 "ptolemy.actor.lib.colt.ColtRandomSource", 268 "ptolemy/actor/lib/colt/colt-copyright.htm"); 269 _addIfClassPresent(copyrightsMap, 270 "ptolemy.actor.lib.database.DatabaseManager", 271 "com.mysql.jdbc.Driver", 272 "ptolemy/actor/lib/database/mysql-copyright.htm"); 273 _addIfClassPresent(copyrightsMap, "ptolemy.actor.lib.excel.Excel", 274 "ptolemy/actor/lib/excel/jxl-copyright.htm"); 275 _addIfClassPresent(copyrightsMap, 276 "ptolemy.actor.lib.fmi.fmipp.FMUModelExchange", 277 "ptolemy/actor/lib/fmi/fmipp/fmipp-license.htm"); 278 /* ptolemy.actor.lib.io.comm.SerialComm */ 279 _addIfClassPresent(copyrightsMap, "gnu.io.SerialPort", 280 "lib/nrjavaserial-license.htm"); 281 _addIfClassPresent(copyrightsMap, "ptolemy.actor.lib.jai.JAIImageToken", 282 "ptolemy/actor/lib/jai/jai-copyright.htm"); 283 _addIfClassPresent(copyrightsMap, "ptolemy.actor.lib.jjs.JavaScript", 284 "ptolemy/actor/lib/jjs/jjs-license.htm"); 285 _addIfFilePresent(copyrightsMap, 286 "$CLASSPATH/ptolemy/actor/lib/jjs/external/require.js", 287 "ptolemy/actor/lib/jjs/external/require.js-license.htm"); 288 289 _addIfClassPresent(copyrightsMap, "ptolemy.actor.lib.jmf.JMFImageToken", 290 "ptolemy/actor/lib/jmf/jmf-copyright.htm"); 291 _addIfClassPresent(copyrightsMap, "ptolemy.actor.lib.joystick.Joystick", 292 "ptolemy/actor/lib/joystick/joystick-copyright.htm"); 293 _addIfClassPresent(copyrightsMap, 294 "ptolemy.actor.lib.logic.fuzzy.FuzzyLogic", 295 "ptolemy/actor/lib/logic/fuzzy/FuzzyEngine-copyright.htm"); 296 _addIfClassPresent(copyrightsMap, "javax.mail.Address", 297 "lib/javamail-license.htm"); 298 _addIfClassPresent(copyrightsMap, "org.ptolemy.opencv.FaceRecognizer", 299 "lib/opencv-license.htm"); 300 _addIfClassPresent(copyrightsMap, 301 "ptolemy.actor.lib.python.PythonScript", 302 "ptolemy/actor/lib/python/jython-license.htm"); 303 _addIfClassPresent(copyrightsMap, "ptolemy.actor.lib.x10.X10Interface", 304 "ptolemy/actor/lib/x10/x10-copyright.htm"); 305 _addIfClassPresent(copyrightsMap, "ptolemy.actor.ptalon.PtalonActor", 306 "ptolemy/actor/ptalon/ptalon-copyright.html"); 307 308 _addIfClassPresent(copyrightsMap, 309 "ptolemy.backtrack.eclipse.ast.TypeAnalyzer", 310 "ptolemy/backtrack/eclipse/ast/eclipse-copyright.htm"); 311 312 _addIfClassPresent(copyrightsMap, 313 "ptolemy.backtrack.util.ClassFileLoader", 314 "ptolemy/backtrack/util/gcj-copyright.html"); 315 316 _addIfClassPresent(copyrightsMap, 317 "ptolemy.caltrop.actors.AbstractCalInterpreter", 318 "ptolemy/caltrop/cup-copyright.htm"); 319 _addIfClassPresent(copyrightsMap, 320 "ptolemy.caltrop.actors.CalInterpreter", 321 "ptolemy/caltrop/saxon-copyright.htm"); 322 323 _addIfClassPresent(copyrightsMap, 324 "ptolemy.ptolemy.cg.kernel.generic.program.procedural.fmima.FMIMACodeGenerator", 325 "ptolemy/actor/lib/fmi/ma2/fmusdk-license.htm"); 326 327 _addIfClassPresent(copyrightsMap, 328 "ptolemy.copernicus.kernel.KernelMain", 329 "ptolemy/copernicus/kernel/soot-copyright.html"); 330 331 _addIfClassPresent(copyrightsMap, "ptolemy.data.ontologies.Concept", 332 "ptolemy/data/ontologies/doc/udunits2Database/udunits-license.htm"); 333 334 _addIfClassPresent(copyrightsMap, "ptolemy.domains.gr.kernel.GRActor", 335 "ptolemy/domains/gr/lib/java3d-copyright.htm"); 336 _addIfClassPresent(copyrightsMap, 337 "ptolemy.domains.gr.lib.quicktime.MovieViewScreen2D", 338 "ptolemy/domains/gr/lib/quicktime/quicktime-copyright.htm"); 339 _addIfClassPresent(copyrightsMap, 340 "ptolemy.domains.gr.lib.vr.GRTexture2D.java", 341 "ptolemy/domains/gr/lib/vr/vr-copyright.htm"); 342 343 _addIfClassPresent(copyrightsMap, 344 "ptolemy.domains.gro.kernel.GRODirector", 345 "ptolemy/domains/gro/JOGL-copyright.htm"); 346 347 _addIfClassPresent(copyrightsMap, 348 "ptolemy.domains.psdf.kernel.PSDFScheduler", 349 "ptolemy/domains/psdf/mapss-copyright.htm"); 350 351 _addIfClassPresent(copyrightsMap, 352 "ptolemy.domains.ptinyos.util.nc2moml.MoMLLib", 353 "ptolemy/domains/ptinyos/lib/jdom-copyright.htm"); 354 355 _addIfClassPresent(copyrightsMap, "ptolemy.graph.Element", 356 "ptolemy/graph/graph-license.htm"); 357 358 _addIfClassPresent(copyrightsMap, "ptolemy.gui.ComponentDialog", 359 "ptolemy/gui/ComponentDialog-license.htm"); 360 361 _addIfClassPresent(copyrightsMap, 362 "ptolemy.homer.widgets.ResizableImageWidget", 363 "ptolemy/homer/widgets/ResizableImageWidget-license.htm"); 364 365 _addIfClassPresent(copyrightsMap, "ptolemy.matlab.Expression", 366 "ptolemy/matlab/matlab-copyright.htm"); 367 368 _addIfClassPresent(copyrightsMap, "ptolemy.media.Audio", 369 "ptolemy/media/Audio-license.htm"); 370 371 _addIfClassPresent(copyrightsMap, "ptolemy.util.DoubleUtilities", 372 "ptolemy/util/DoubleUtilities-license.htm"); 373 374 _addIfClassPresent(copyrightsMap, "ptolemy.util.test.junit.TclTests", 375 "lib/JUnitParams-license.htm"); 376 377 _addIfClassPresent(copyrightsMap, 378 "ptolemy.vergil.basic.export.html.ExportHTMLAction", 379 "ptolemy/vergil/basic/export/html/javascript/javascript-license.htm"); 380 381 _addIfClassPresent(copyrightsMap, 382 "ptolemy.vergil.basic.export.html.ExportToWeb", 383 "ptolemy/vergil/basic/export/html/javascript/fancybox/fancybox-license.htm"); 384 385 _addIfClassPresent(copyrightsMap, 386 "ptolemy.vergil.basic.export.itextpdf.ExportPDFAction", 387 "ptolemy/vergil/basic/export/itextpdf/itextpdf-copyright.htm"); 388 389 _addIfClassPresent(copyrightsMap, 390 "ptolemy.vergil.basic.layout.kieler.KielerLayout", 391 "lib/guava-license.htm"); 392 _addIfClassPresent(copyrightsMap, 393 "ptolemy.vergil.basic.layout.kieler.KielerGraphUtil", 394 "ptolemy/vergil/basic/layout/kieler/kieler-copyright.htm"); 395 396 _addIfClassPresent(copyrightsMap, 397 "ptolemy.vergil.pdfrenderer.PDFAttribute", 398 "ptolemy/vergil/pdfrenderer/PDFRenderer-copyright.htm"); 399 400 _addIfClassPresent(copyrightsMap, "tcl.lang.Shell", 401 "lib/ptjacl-license.htm"); 402 403 _addIfClassPresent(copyrightsMap, 404 "thales.vergil.SingleWindowApplication", 405 "thales/thalesSingleWindow-license.htm"); 406 407 _addIfClassPresent(copyrightsMap, 408 "org.jivesoftware.smack.XMPPConnection", 409 "lib/smack-license.htm"); 410 411 // Check for the _applicationCopyrights parameter 412 try { 413 Parameter applicationCopyrights = (Parameter) configuration 414 .getAttribute("_applicationCopyrights", Parameter.class); 415 416 if (applicationCopyrights != null) { 417 ArrayToken copyrightTokens = (ArrayToken) applicationCopyrights 418 .getToken(); 419 420 for (int i = 0; i < copyrightTokens.length(); i++) { 421 StringToken actorToken = (StringToken) ((RecordToken) copyrightTokens 422 .getElement(i)).get("actor"); 423 StringToken copyrightToken = (StringToken) ((RecordToken) copyrightTokens 424 .getElement(i)).get("copyright"); 425 _addIfClassPresent(copyrightsMap, actorToken.stringValue(), 426 copyrightToken.stringValue()); 427 } 428 } 429 } catch (Exception ex) { 430 // This application has no _applicationCopyrights 431 } 432 433 // We also create a file that contains all the copyrights. 434 StringBuffer masterCopyrightBuffer = new StringBuffer(); 435 436 StringBuffer masterCopyrightTable = new StringBuffer(); 437 438 // Read in the header 439 String copyrightStartFileName = "$CLASSPATH/ptolemy/actor/gui/masterCopyrightStart.htm.in"; 440 try { 441 // Probably wrong to read it as bytes and convert to a 442 // string, but we have a convenient method, so we use it. 443 masterCopyrightBuffer.append(new String( 444 FileUtilities.binaryReadURLToByteArray(FileUtilities 445 .nameToURL(copyrightStartFileName, null, null)))); 446 } catch (IOException ex) { 447 // Print only a message, we want to print the copyrights 448 System.err.println( 449 "Could not read " + copyrightStartFileName + ": " + ex); 450 } 451 452 StringBuffer htmlBuffer = new StringBuffer( 453 generatePrimaryCopyrightHTML(configuration)); 454 455 // Sort by the copyright file name, which should start with the package name. 456 FileNameComparator fileNameComparator = new FileNameComparator(); 457 TreeMap<String, Set<String>> sortedCopyrightsMap = new TreeMap<String, Set<String>>( 458 fileNameComparator); 459 460 sortedCopyrightsMap.putAll(copyrightsMap); 461 462 if (copyrightsMap.size() != sortedCopyrightsMap.size()) { 463 // Print only a message, we want to print the copyrights. 464 System.err.println( 465 "GenerateCopyrights: the size of the unsorted copyright table " 466 + "and the sorted copyright table are not the same? Perhaps there are two " 467 + "or more copyrights with the same file name? (foo/copyright.htm and " 468 + "bar/copyright.htm will not work.)"); 469 470 } 471 Iterator copyrights = sortedCopyrightsMap.entrySet().iterator(); 472 if (copyrights.hasNext()) { 473 // DSP configuration might not include other actors. 474 htmlBuffer.append("<p>Below we list features and the " 475 + "corresponding copyright " 476 + " of the package that is used. If a feature is not " 477 + "listed below, then the " 478 + _getApplicationName(configuration) + " copyright is the " 479 + "only copyright." + "<table>\n" + " <tr>\n" 480 + " <th>Copyright of package used by the feature</th>\n" 481 + " <th>Feature</th>\n" + " </tr>\n"); 482 483 while (copyrights.hasNext()) { 484 Map.Entry entry = (Map.Entry) copyrights.next(); 485 String copyrightURL = (String) entry.getKey(); 486 Set entitiesSet = (Set) entry.getValue(); 487 488 StringBuffer entityBuffer = new StringBuffer(); 489 Iterator entities = entitiesSet.iterator(); 490 491 while (entities.hasNext()) { 492 if (entityBuffer.length() > 0) { 493 entityBuffer.append(", "); 494 } 495 496 String entityClassName = (String) entities.next(); 497 498 // If we have javadoc, link to it. 499 // Assuming that entityClassName contains a dot separated 500 // classpath here. 501 String docName = "doc.codeDoc." + entityClassName; 502 String codeDoc = _findURL( 503 docName.replace('.', '/') + ".html"); 504 entityBuffer.append("<a href=\"" + codeDoc + "\">" 505 + entityClassName + "</a>"); 506 } 507 508 //System.out.println("GenerateCopyrights: url: " + copyrightURL); 509 String foundCopyright = _findURL(copyrightURL); 510 511 if (copyrightURL.contains("backtrack") 512 && !copyrightURL.contains("http")) { 513 // If the backtrack copyright is not local, then don't print it. 514 continue; 515 } 516 htmlBuffer.append("<tr>\n" + " <td> <a href=\"" 517 + foundCopyright + "\"><code>" 518 + _canonicalizeURLToPTII(foundCopyright) 519 + "</code></a></td>\n" + " <td>" + entityBuffer 520 + "</td>\n" + "</tr>\n"); 521 try { 522 String copyright = new String(FileUtilities 523 .binaryReadURLToByteArray(new URL(foundCopyright))); 524 525 // Append the text between the body tags. 526 527 // Look for <body> or </head> 528 int startIndex = 0; 529 if ((startIndex = copyright.indexOf("<body>")) == -1) { 530 if ((startIndex = copyright.indexOf("</head>")) != -1) { 531 startIndex += "</head>".length(); 532 } else { 533 // Print only a message, we want to print the copyrights. 534 System.out.println("Could not find body or head in " 535 + foundCopyright + " " 536 + copyright.substring(0, 200)); 537 startIndex = 0; 538 } 539 } else { 540 startIndex += "<body>".length(); 541 } 542 543 // Look for </body> or </html> 544 int endIndex = 0; 545 if ((endIndex = copyright.indexOf("</body>")) == -1) { 546 if ((endIndex = copyright.indexOf("</html>")) == -1) { 547 endIndex = copyright.length(); 548 } 549 } 550 551 // Get read of the html head and close body. 552 copyright = copyright.substring(startIndex, endIndex); 553 554 // If there is a <h1> tag, make sure that it has <a name=... 555 int hIndex = 0; 556 if ((hIndex = copyright.indexOf("<h1>")) == -1) { 557 if ((hIndex = copyright.indexOf("<h2>")) == -1) { 558 // Print only a message, we want to print the copyrights. 559 System.out.println("Warning, no h1 or h2 in " 560 + foundCopyright); 561 } else { 562 } 563 } 564 if (hIndex != -1) { 565 int hEndIndex = copyright.indexOf("</h"); 566 if (hEndIndex < hIndex) { 567 throw new RuntimeException("Generating copyrights: " 568 + "hEndIndex " + hEndIndex + " < " + hIndex 569 + " " + foundCopyright + " copyright:\n" 570 + copyright); 571 } 572 String header = copyright.substring(hIndex, hEndIndex); 573 String newHeader = header; 574 if (header.indexOf("<a name") == -1) { 575 // Insert a name tag that is the name of the package. 576 577 // If the copyright file name contains a -,then the name of the package 578 // is what is before the -. If the name does not have a -, then 579 // the package name is the directory. 580 String packageName = "unknownPackage"; 581 File copyrightFile = new File(copyrightURL); 582 String copyrightFileName = copyrightFile.getName(); 583 int hyphenIndex = 0; 584 if ((hyphenIndex = copyrightFileName 585 .indexOf("-")) > 0) { 586 packageName = copyrightFileName.substring(0, 587 hyphenIndex); 588 } else { 589 packageName = copyrightFile.getParent(); 590 } 591 newHeader = "<a name=\"" + packageName + "\">" 592 + header; 593 copyright = copyright.replace(header, newHeader); 594 } 595 596 int nameIndex = 0; 597 if ((nameIndex = newHeader 598 .indexOf("<a name=\"")) != -1) { 599 int labelIndex = 0; 600 if ((labelIndex = newHeader.indexOf("\">")) != -1) { 601 String target = newHeader.substring( 602 nameIndex + "<a name=\"".length(), 603 labelIndex); 604 // Skip the <h1> or <h2> 605 String label = newHeader 606 .substring(labelIndex + 6); 607 608 //_guessCopyright(label, copyright); 609 610 masterCopyrightTable 611 .append(_generateLicenseTableRow(target, 612 label)); 613 } 614 } 615 } 616 masterCopyrightBuffer.append(copyright); 617 } catch (IOException ex) { 618 // Ignore this, we want to print the copyrights no matter what. 619 System.out.println( 620 "Could not read " + foundCopyright + ": " + ex); 621 } 622 } 623 624 htmlBuffer.append("</table>\n</p>"); 625 } 626 627 String tableTarget = "<!-- Table Contents Goes Here -->"; 628 int tableTargetIndex = -1; 629 if ((tableTargetIndex = masterCopyrightBuffer 630 .indexOf(tableTarget)) == -1) { 631 System.err.println("GenerateCopyrights: Could not find \"" 632 + tableTarget + "\" in the generated copyright text, " 633 + "maybe ptolemy/actor/gui/masterCopyrightStart.htm.in does not have it?"); 634 } else { 635 masterCopyrightBuffer.insert(tableTargetIndex, 636 masterCopyrightTable); 637 } 638 try { 639 URL masterCopyrightURL = HTMLAbout._temporaryHTMLFile( 640 "mastercopyright", ".htm", 641 masterCopyrightBuffer.toString()); 642 htmlBuffer.append("<p>For the complete copyrights in one file\n" 643 + "See the <a href=\"" + masterCopyrightURL 644 + "\">master copyright</a>.</p>\n"); 645 } catch (IOException ex) { 646 // Ignore this, we want to print the copyrights. 647 System.err.println( 648 "Could not write a temporary file with the complete copyrights: " 649 + ex); 650 } 651 652 htmlBuffer.append("<p>Other information <a href=\"about:\">about</a>\n" 653 + "this configuration.\n" + "</body>\n</html>"); 654 655 return htmlBuffer.toString(); 656 } 657 658 /** Generate the primary copyright. Include a link to the other 659 * copyrights. 660 * @param configuration The configuration in which to look for the 661 * _applicationName attribute. 662 * @return A String containing HTML that describes what 663 * copyrights are used by Entities in the configuration 664 */ 665 public static String generatePrimaryCopyrightHTML( 666 Configuration configuration) { 667 668 String defaultApplicationCopyright = "ptolemy/configs/doc/copyright.htm"; 669 String applicationCopyright = defaultApplicationCopyright; 670 671 try { 672 StringAttribute applicationCopyrightAttribute = (StringAttribute) configuration 673 .getAttribute("_applicationCopyright", 674 StringAttribute.class); 675 676 if (applicationCopyrightAttribute != null) { 677 applicationCopyright = applicationCopyrightAttribute 678 .getExpression(); 679 } 680 } catch (Exception ex) { 681 // Ignore and use the default applicationCopyright 682 applicationCopyright = defaultApplicationCopyright; 683 } 684 685 String applicationName = _getApplicationName(configuration); 686 String applicationCopyrightURL = _findURL(applicationCopyright); 687 688 String aelfredCopyright = _findURL( 689 "com/microstar/xml/aelfred-license.htm"); 690 String graphCopyright = _findURL("ptolemy/graph/graph-license.htm"); 691 String doubleUtilitiesCopyright = _findURL( 692 "ptolemy/util/DoubleUtilities-license.htm"); 693 694 String defaultCSS = _findURL("doc/default.css"); 695 StringBuffer htmlBuffer = new StringBuffer(); 696 htmlBuffer.append("<html>\n<head>\n<title>Copyrights</title>\n" 697 + "<link href=\"" + defaultCSS + "\" rel=\"stylesheet\"" 698 + "type=\"text/css\">\n" + "</head>\n<body>\n" + "<h1>" 699 + applicationName + "</h1>\n" + "The primary copyright for the " 700 + applicationName + " System can be\n" + "found in <a href=\"" 701 + applicationCopyrightURL + "\"><code>" 702 + _canonicalizeURLToPTII(applicationCopyrightURL) 703 + "</code></a>.\n" 704 + "This configuration includes code that uses packages\n" 705 + "with the following copyrights.\n"); 706 707 if (!applicationCopyright.equals(defaultApplicationCopyright)) { 708 // If the Ptolemy II copyright is not the main copyright, add it. 709 String ptolemyIICopyright = _findURL(defaultApplicationCopyright); 710 htmlBuffer.append("<p>" + applicationName + " uses Ptolemy II " 711 + VersionAttribute.CURRENT_VERSION.getExpression() + ".\n" 712 + "PtolemyII is covered by the copyright in\n " 713 + "<a href=\"" + ptolemyIICopyright + "\"><code>" 714 + _canonicalizeURLToPTII(ptolemyIICopyright) 715 + "</code></a>\n"); 716 } 717 718 htmlBuffer.append("<p>" + applicationName 719 + " uses AElfred as an XML Parser.\n" 720 + "AElfred is covered by the copyright in\n " + "<a href=\"" 721 + aelfredCopyright + "\"><code>" 722 + _canonicalizeURLToPTII(aelfredCopyright) + "</code></a>\n</p>" 723 + "<p>" + applicationName 724 + " uses the ptolemy.graph package for scheduling and analysis of Ptolemy II models." 725 + "Significant portions of the ptolemy.graph package were developed by " 726 + "<a href=\"http://www.ece.umd.edu/~ssb/#in_browser\">Professor Shuvra S. Bhattacharyya</a> " 727 + "and his group. and are covered by a BSD License in\n " 728 + "<a href=\"" + graphCopyright + "\"><code>" 729 + _canonicalizeURLToPTII(graphCopyright) + "</code></a>\n</p>" 730 + "<p>" + applicationName 731 + " uses DoubleUtilities, which is based on Guava's DoubleUtils.java. " 732 + "Guava is licensed under the Apache License, Version 2.0, see " 733 + "<a href=\"" + doubleUtilitiesCopyright + "\"><code>" 734 + _canonicalizeURLToPTII(doubleUtilitiesCopyright) 735 + "</code></a>\n</p>"); 736 737 return htmlBuffer.toString(); 738 } 739 740 /////////////////////////////////////////////////////////////////// 741 //// private methods //// 742 743 /* If a className is can be found, then add the className 744 * and copyrightPath to copyrightsMap 745 * @param The map of copyrights. 746 * @param applicationClassName The fully qualified, dot separated 747 * class name of an application class, such as a Ptolemy actor 748 * that uses (either by import or by reflection) the libraryClassName. 749 * @param libraryClassName The fully qualified, dot separated 750 * class name of the copyrighted or licensed library. 751 * @param copyrightPath The path or URL to the copyright for 752 * the library 753 */ 754 private static void _addIfClassPresent( 755 Map<String, Set<String>> copyrightsMap, String applicationClassName, 756 String libraryClassName, String copyrightPath) { 757 // If actor.lib.database.DatabaseManager is present, then 758 // we look for MySQL JDBC packages. 759 try { 760 Class.forName(applicationClassName); 761 _addIfClassPresent(copyrightsMap, libraryClassName, copyrightPath); 762 } catch (Throwable throwable) { 763 // Ignore, this just means that the applicationClassName 764 // could not be found, so we need not include information 765 // about the copyright. 766 } 767 } 768 769 /* If a className is can be found, then add the className 770 * and copyrightPath to copyrightsMap 771 * @param The map of copyrights. 772 * @param className The fully qualified, dot separated 773 * class name of the copyrighted or licensed library. 774 * @param copyrightPath The path or URL to the copyright for 775 * the library. 776 */ 777 private static void _addIfClassPresent( 778 Map<String, Set<String>> copyrightsMap, String className, 779 String copyrightPath) { 780 781 boolean addIt = false; 782 783 try { 784 Class.forName(className); 785 addIt = true; 786 } catch (Throwable throwable) { 787 // Usually, ignore, this just means that the classname could 788 // not be found, so we need not include information 789 // about the copyright. 790 791 // However, under MacOSX, include any backtracking links 792 String osName = System.getProperty("os.name"); 793 if (osName.startsWith("Mac OS") 794 && copyrightPath.contains("backtrack")) { 795 addIt = true; 796 } 797 } 798 799 if (addIt) { 800 try { 801 Set<String> entitiesSet = copyrightsMap.get(copyrightPath); 802 803 if (entitiesSet == null) { 804 // This is the first time we've seen this copyright, 805 // add a key/value pair to copyrights, where the key 806 // is the URL of the copyright and the value is Set 807 // of entities that correspond with that copyright. 808 entitiesSet = new HashSet<String>(); 809 810 entitiesSet.add(className); 811 copyrightsMap.put(copyrightPath, entitiesSet); 812 } else { 813 // Other classes are using this copyright, so add this 814 // one to the list. 815 entitiesSet.add(className); 816 } 817 } catch (Throwable throwable) { 818 // Ignore errors, it must means we 819 } 820 } 821 } 822 823 /* If a file name can be found as a resource, then add 824 * the file name and copyrightPath to copyrightsMap 825 * @param The map of copyrights. 826 * @param fileName The filename that begins with "$CLASSPATH", for example 827 * "$CLASSPATH/bin/Vergil.app/Contents/MacOS/universalJavaApplicationStub" 828 * @param copyrightPath The path or URL to the copyright for 829 * the library, for example 830 * "bin/Vergil.app/Contents/MacOS/universalJavaApplicationStub-license.html" 831 */ 832 private static void _addIfFilePresent( 833 Map<String, Set<String>> copyrightsMap, String fileName, 834 String copyrightPath) { 835 836 boolean addIt = false; 837 838 try { 839 File file = FileUtilities.nameToFile(fileName, null); 840 if (file == null) { 841 return; 842 } else if (file.isFile()) { 843 addIt = true; 844 } 845 } catch (Throwable throwable) { 846 // Usually, ignore, this just means that the classname could 847 // not be found, so we need not include information 848 // about the copyright. 849 } 850 851 if (addIt) { 852 try { 853 Set<String> entitiesSet = copyrightsMap.get(copyrightPath); 854 855 if (entitiesSet == null) { 856 // This is the first time we've seen this copyright, 857 // add a key/value pair to copyrights, where the key 858 // is the URL of the copyright and the value is Set 859 // of entities that correspond with that copyright. 860 entitiesSet = new HashSet<String>(); 861 862 entitiesSet.add(fileName); 863 copyrightsMap.put(copyrightPath, entitiesSet); 864 } else { 865 // Other classes are using this copyright, so add this 866 // one to the list. 867 entitiesSet.add(fileName); 868 } 869 } catch (Throwable throwable) { 870 // Ignore errors. 871 } 872 } 873 } 874 875 // Truncate a jarURL so that the very long jar:file:...! is 876 // converted to $PTII. If the string does not start with jar:file 877 // or if it startes with jar:file but does not contain a !, then 878 // it is returned unchanged. This method is used to truncate 879 // the very long paths that we might see under Web Start. 880 private static String _canonicalizeURLToPTII(String path) { 881 if (!path.startsWith("jar:file")) { 882 return path; 883 } else { 884 int index = path.lastIndexOf("!"); 885 886 if (index == -1) { 887 return path; 888 } else { 889 return "$PTII" + path.substring(index + 1, path.length()); 890 } 891 } 892 } 893 894 // Look for the localURL, and if we cannot find it, refer 895 // to the url on the website that corresponds with this version of 896 // Ptolemy II 897 private static String _findURL(String localURL) { 898 try { 899 URL url = ClassUtilities.getResource(localURL); 900 return url.toString(); 901 } catch (Exception ex) { 902 // Ignore it and use the copyright from the website 903 // Substitute in the first two tuples of the version 904 // If the version is 3.0-beta-2, we end up with 3.0 905 StringBuffer majorVersionBuffer = new StringBuffer(); 906 907 Iterator tuples = VersionAttribute.CURRENT_VERSION.iterator(); 908 909 // Get the first two tuples and separate them with a dot. 910 if (tuples.hasNext()) { 911 majorVersionBuffer.append((String) tuples.next()); 912 913 if (tuples.hasNext()) { 914 majorVersionBuffer.append("."); 915 majorVersionBuffer.append((String) tuples.next()); 916 } 917 } 918 919 String majorVersion = majorVersionBuffer.toString(); 920 return "http://ptolemy.eecs.berkeley.edu/ptolemyII/" + "ptII" 921 + majorVersion + "/ptII" + majorVersion + "/" + localURL; 922 } 923 } 924 925 /** Generate a row for the master table. 926 * @param target The HTML target for the license 927 * @param label The label for the license. 928 * @return HTML for the row that represents the table. 929 */ 930 private static String _generateLicenseTableRow(String target, 931 String label) { 932 StringBuffer results = new StringBuffer(" <tr>\n" + " <td>\n" 933 + " <a href=\"#" + target + "\">" 934 + label.replace("License for", "").replace("Copyright for", "") 935 + "</a>\n" + " </td>\n"); 936 int rowIndex = -1; 937 for (int i = 0; i < _licenses.length; i++) { 938 if (_licenses[i][0].equals(target)) { 939 rowIndex = i; 940 break; 941 } 942 } 943 if (rowIndex == -1) { 944 results.append( 945 " <td>?</td> <td>?</td> <td>?</td> <td>Update ptolemy/actor/gui/GenerateCopyrights.java for \"" 946 + target + "\".</td>"); 947 } else { 948 results.append(" <td>" + _licenses[rowIndex][1] + "</td>\n" 949 + " <td>" + _licenses[rowIndex][2] + "</td>\n" + " <td>" 950 + _licenses[rowIndex][3] + "</td>\n" + " <td>" 951 + _licenses[rowIndex][4] + "</td>\n" + " <td>" 952 + _licenses[rowIndex][5] + "</td>\n"); 953 } 954 results.append("</tr>\n"); 955 return results.toString(); 956 } 957 958 /** Get the application name from the _applicationName parameter. 959 * If the _applicationName parameter is not set, then return 960 * "Ptolemy II" 961 */ 962 private static String _getApplicationName(Configuration configuration) { 963 // Now generate the HTML 964 String applicationName = "Ptolemy II"; 965 966 try { 967 StringAttribute applicationNameAttribute = (StringAttribute) configuration 968 .getAttribute("_applicationName", StringAttribute.class); 969 970 if (applicationNameAttribute != null) { 971 applicationName = applicationNameAttribute.getExpression(); 972 } 973 } catch (Exception ex) { 974 // Ignore and use the default applicationName 975 } 976 return applicationName; 977 } 978 979 // /** Guess the type of copyright, used for priming the table. */ 980 // protected void _guessCopyright(String label, String copyright) { 981 // StringBuffer type = new StringBuffer(); 982 // String [] types = {"Apache License", "CDDL", "Eclipse", "GNU Lesser General Public", "Oracle", "Research in Motion", "Sun" }; 983 // for (int i = 0; i < types.length; i++) { 984 // if (copyright.indexOf(types[i]) != -1) { 985 // if (type.length() > 0) { 986 // type.append(" + "); 987 // } 988 // type.append(types[i]); 989 // } 990 // } 991 // System.out.println("{\"" + target + "\", \" \", \" \", \"Y\", \"" 992 // + type + "\"},"); 993 // } 994 995 /** Compare two filenames. 996 */ 997 static class FileNameComparator implements Comparator<String> { 998 999 /** Compare to Strings that should represent files by the 1000 * lower case name of the file. 1001 * @param a The first file name. 1002 * @param b The second file name. 1003 * @return -1, 0 or 1 1004 */ 1005 @Override 1006 public int compare(String a, String b) { 1007 File fileA = new File(a); 1008 File fileB = new File(b); 1009 return fileA.getName().toLowerCase() 1010 .compareTo(fileB.getName().toLowerCase()); 1011 } 1012 } 1013 1014 /** A table of copyright labels, whether it is in Ptiny, the 1015 * Windows JRE, included in sources, included in Kepler and a 1016 * summary of the license(s). 1017 * We use a simple table here for ease of maintenance. 1018 */ 1019 private static String[][] _licenses = { 1020 // Name, Ptiny, Windows JRE, Included in Sources, Included in Kepler, Summary 1021 { "accessors", " ", " ", "Y", "Y", "BSD and MIT" }, 1022 { "aelfred", "Y", " ", "Y", "Y", "Include Microstar's copyright" }, 1023 { "Audio", "Y", " ", "Y", "Y ", "Include credit text" }, 1024 { "BrowserLauncher", "Y", " ", "Y", "Y", 1025 "Include the BrowserLauncher copyright" }, 1026 { "ComponentDialog", "Y", " ", "Y", "Y", 1027 "Oracle BSD Example License" }, 1028 { "DoubleUtilities", "Y", " ", "Y", "Y", "Apache License" }, 1029 { "JUnitParams", " ", " ", "Y", "Y", "Apache License" }, 1030 { "javamail", " ", " ", "Y", " ", 1031 "CDDL + GPLv2 with Classpath exception" }, 1032 { "PortConfigurerDialog", "Y", " ", "Y", "Y", 1033 "Oracle BSD Example License" }, 1034 { "PDFRenderer", " ", " ", "Y", "Y", "GNU Lesser General Public" }, 1035 { "ResizableImageWidget", " ", " ", "Y", " ", 1036 "CDDL + Oracle + Oracle" }, 1037 { "april", " ", " ", " ", "Y ", "BSD" }, 1038 { "chic", " ", " ", "Y", "Y", "BSD" }, 1039 { "colt", "Y", " ", "Y", "Y", "BSD and others" }, 1040 { "commons", "N", " ", "Y", "Y", "Apache" }, 1041 { "cup", " ", " ", "Y", " ", "Similar to BSD" }, 1042 { "db", " ", " ", "Y", " ", 1043 "Similar to <font color=\"red\">GPL</font>" }, // GPL!! 1044 { "fmipp", " ", " ", "Y", " ", "FMUSDK: Qtronic: Similar to BSD" }, 1045 { "fmusdk", " ", " ", "Y", " ", " QTronic: Similar to BSD" }, 1046 { "g4ltl", " ", " ", "Y", "Y", "Apache License" }, 1047 { "gcj", " ", " ", "Y", " ", "GPL with libgcc Exception" }, // Backtracking. 1048 { "graph", "Y", " ", "Y", "Y", "BSD" }, 1049 { "guava", " ", " ", "Y", "Y", "Apache License" }, 1050 { "hazelcast", " ", " ", "Y", " ", "Apache License" }, 1051 { "itextpdf", " ", " ", "Y", " ", 1052 "Affero General Public License <font color=\"red\">like GPL</font>" }, 1053 { "jackson", " ", " ", "Y", " ", "Apache License" }, 1054 { "jai", " ", "Y", " ", " ", "Oracle" }, 1055 { "java3d", " ", "Y", "", " ", "Oracle" }, 1056 { "javascript", " ", " ", "Y", "Y", "JQuery and Fancybox: MIT" }, 1057 { "javax.servlet", " ", " ", "Y", "Y", "Apache License" }, 1058 { "jcerti", " ", " ", "Y", "Y", "GNU Lesser General Public" }, 1059 { "jcobyla", " ", " ", "Y", "", "MIT" }, 1060 { "jdom", " ", " ", "Y", "", 1061 "Similar to BSD. No use of sponsor name in advertising" }, 1062 { "jetty", " ", " ", "Y", "Y", "Apache License + Eclipse" }, 1063 { "jgoodies", " ", " ", "Y", "Y", "3 Clause BSD" }, 1064 { "jhlabs", " ", " ", "Y", " ", "Apache License" }, 1065 { "jimblacklerUtils", " ", " ", "Y", "Y", "Public Domain" }, 1066 { "jjs", " ", " ", "Y", " ", "BSD-like" }, 1067 { "jmf", " ", "Y", " ", " ", "Oracle" }, 1068 { "jna", " ", " ", "Y", "Y", 1069 "Apache License + GNU Lesser General Public" }, 1070 { "JRI", " ", "Y", " ", " ", "GNU Lesser General Public" }, 1071 { "joystick", " ", " ", "Y", " ", "Artistic License" }, 1072 { "js", " ", " ", "Y", " ", "Mozilla + Oracle" }, 1073 { "json", " ", " ", "Y", "Y", "BSD-like" }, 1074 { "jsoup", " ", " ", "Y", "Y", "MIT" }, 1075 { "junit", " ", " ", "Y", "Y", "Common Public License - v 1.0" }, 1076 { "jxl", " ", " ", "Y", " ", "GNU Lesser General Public" }, 1077 { "jython", "Y", " ", "Y", "Y", 1078 "Apache License + Python V2 + other licenses" }, 1079 { "kieler", "Y", " ", "Y", "Y", "Eclipse" }, 1080 { "mapss", " ", " ", "Y", "Y", "BSD" }, 1081 { "matlab", "Y", " ", "Y", "Y", "Research in Motion BSD" }, 1082 { "mlc", " ", " ", "Y", "Y", "GNU Lesser General Public + Oracle" }, 1083 { "mysql", " ", " ", "Y", " ", "GPL + exceptions or Commercial" }, 1084 { "netbeans", " ", " ", "Y", "Y", "CDDL + Oracle" }, 1085 { "netty", " ", " ", " ", "Y ", "Apache + MIT + BSD + PD" }, 1086 { "nrjavaserial", " ", " ", "Y", " ", "LGPL 2.1 + Apache" }, 1087 { "opencv", " ", " ", "Y", " ", "BSD" }, 1088 { "org.apache.oltu.oauth2", " ", " ", " ", "Y ", "Apache" }, 1089 { "org.eclipse.paho.client.mqttv3", " ", " ", " ", "Y", "Eclipse" }, 1090 { "oscP5", " ", " ", " ", "Y ", 1091 "GNU Lesser General Public License 3.0" }, 1092 { "protobuf", " ", " ", "Y", "Y", "BSD 3-Clause" }, 1093 { "ptalon", "Y", " ", "Y", " ", "Antler: Public Domain" }, 1094 { "ptjacl", " ", " ", "Y", "Y", "Apache License + BSD + Oracle" }, 1095 { "quicktime", " ", " ", " ", " ", "Apple" }, // License prohibits distribution 1096 { "require.js", " ", " ", "Y", " ", "MIT" }, 1097 { "rxtx", " ", "Y", " ", " ", 1098 "GNU Lesser General Public 2.1 + Oracle" }, 1099 { "saxon", " ", " ", "Y", " ", "Mozilla Public License" }, 1100 { "smack", " ", " ", "Y", "Y", "Apache License" }, 1101 { "socketio", " ", " ", "Y", "Y", "BSD" }, 1102 { "soot", " ", " ", "Y", "Y", "BSD + LGPL 2" }, 1103 { "sphinx", " ", " ", "N", "N", "BSD-like" }, 1104 { "svgSalamander", " ", " ", "Y", " ", "BSD" }, 1105 { "thalesSingleWindow", " ", " ", "Y", " ", "BSD" }, 1106 { "udunits", " ", " ", "Y", " ", 1107 "Similar to BSD. No use of sponsor name in advertising" }, 1108 { "universalJavaApplicationStub", " ", " ", " ", " ", "MIT" }, 1109 { "vertx", " ", " ", "Y", " ", "Apache License" }, 1110 { "webcam", " ", " ", "Y", " ", "BSD and Apache Licenses" } }; 1111}