diff -r 5cee832cf3ae nbbuild/cluster.properties --- a/nbbuild/cluster.properties Thu Apr 21 14:18:17 2011 -0400 +++ b/nbbuild/cluster.properties Tue May 03 21:25:20 2011 +0200 @@ -318,6 +318,7 @@ libs.xerces,\ localhistory,\ mercurial,\ + netbinox,\ o.apache.xml.resolver,\ o.mozilla.rhino.patched,\ o.n.swing.dirchooser,\ diff -r 5cee832cf3ae netbinox/build.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/build.xml Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.netbeans.modules.netbinox + + diff -r 5cee832cf3ae netbinox/external/binaries-list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/external/binaries-list Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,1 @@ +1D63B972926D053DFA427CA03841F67D4EAC6DB2 org.eclipse.osgi_3.6.0.v20100517.jar diff -r 5cee832cf3ae netbinox/external/org.eclipse.osgi_3.6.0.v20100517-license.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/external/org.eclipse.osgi_3.6.0.v20100517-license.txt Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,73 @@ +Name: Equinox +Version: 3.6.0 +Description: Eclipse OSGi container +License: EPL-v10 +OSR: XXX +Files: org.eclipse.osgi_3.6.0.v20100517.jar +Origin: http://www.eclipse.org/equinox/ + +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: + +i) changes to the Program, and +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. +"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. +"Program" means the Contributions distributed in accordance with this Agreement. +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: +a) it complies with the terms and conditions of this Agreement; and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff -r 5cee832cf3ae netbinox/manifest.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/manifest.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,73 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.netbeans.modules.netbinox +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/netbinox/Bundle.properties +OpenIDE-Module-Specification-Version: 1.22 +OpenIDE-Module-Provides: org.osgi.framework.launch.FrameworkFactory +OpenIDE-Module-Hide-Classpath-Packages: org.eclipse.core.runtime.**,org.eclipse.osgi.** +Covered-Packages: META-INF,,org.netbeans.modules.netbinox, + /MANIFEST.MF,/generated-layer.xml,META-INF.services, + /services/org.osgi.framework.launch.FrameworkFactory, + org.osgi.service.framework, + META-INF.services, + org.eclipse, + org.eclipse.core, + org.eclipse.core.runtime, + org.eclipse.core.runtime.adaptor, + org.eclipse.core.runtime.internal, + org.eclipse.core.runtime.internal.adaptor, + org.eclipse.core.runtime.internal.stats, + org.eclipse.osgi, + org.eclipse.osgi.baseadaptor, + org.eclipse.osgi.baseadaptor.bundlefile, + org.eclipse.osgi.baseadaptor.hooks, + org.eclipse.osgi.baseadaptor.loader, + org.eclipse.osgi.event, + org.eclipse.osgi.framework, + org.eclipse.osgi.framework.adaptor, + org.eclipse.osgi.framework.console, + org.eclipse.osgi.framework.debug, + org.eclipse.osgi.framework.eventmgr, + org.eclipse.osgi.framework.internal, + org.eclipse.osgi.framework.internal.core, + org.eclipse.osgi.framework.internal.protocol, + org.eclipse.osgi.framework.internal.protocol.bundleentry, + org.eclipse.osgi.framework.internal.protocol.bundleresource, + org.eclipse.osgi.framework.internal.protocol.reference, + org.eclipse.osgi.framework.internal.reliablefile, + org.eclipse.osgi.framework.log, + org.eclipse.osgi.framework.util, + org.eclipse.osgi.internal, + org.eclipse.osgi.internal.baseadaptor, + org.eclipse.osgi.internal.composite, + org.eclipse.osgi.internal.loader, + org.eclipse.osgi.internal.loader.buddy, + org.eclipse.osgi.internal.module, + org.eclipse.osgi.internal.permadmin, + org.eclipse.osgi.internal.profile, + org.eclipse.osgi.internal.provisional, + org.eclipse.osgi.internal.provisional.service, + org.eclipse.osgi.internal.provisional.service.security, + org.eclipse.osgi.internal.provisional.verifier, + org.eclipse.osgi.internal.resolver, + org.eclipse.osgi.internal.service, + org.eclipse.osgi.internal.service.security, + org.eclipse.osgi.internal.serviceregistry, + org.eclipse.osgi.internal.signedcontent, + org.eclipse.osgi.launch, + org.eclipse.osgi.service, + org.eclipse.osgi.service.datalocation, + org.eclipse.osgi.service.debug, + org.eclipse.osgi.service.environment, + org.eclipse.osgi.service.internal, + org.eclipse.osgi.service.internal.composite, + org.eclipse.osgi.service.localization, + org.eclipse.osgi.service.pluginconversion, + org.eclipse.osgi.service.resolver, + org.eclipse.osgi.service.runnable, + org.eclipse.osgi.service.security, + org.eclipse.osgi.service.urlconversion, + org.eclipse.osgi.signedcontent, + org.eclipse.osgi.storagemanager, + org.eclipse.osgi.util +AutoUpdate-Show-In-Client: false + diff -r 5cee832cf3ae netbinox/nbproject/project.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/nbproject/project.properties Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,45 @@ +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. +# +# Oracle and Java are registered trademarks of Oracle and/or its affiliates. +# Other names may be trademarks of their respective owners. +# +# The contents of this file are subject to the terms of either the GNU +# General Public License Version 2 only ("GPL") or the Common +# Development and Distribution License("CDDL") (collectively, the +# "License"). You may not use this file except in compliance with the +# License. You can obtain a copy of the License at +# http://www.netbeans.org/cddl-gplv2.html +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the +# specific language governing permissions and limitations under the +# License. When distributing the software, include this License Header +# Notice in each file and include the License file at +# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the GPL Version 2 section of the License file that +# accompanied this code. If applicable, add the following below the +# License Header, with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# Contributor(s): +# +# The Original Software is NetBeans. The Initial Developer of the Original +# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun +# Microsystems, Inc. All Rights Reserved. +# +# If you wish your version of this file to be governed by only the CDDL +# or only the GPL Version 2, indicate your decision by adding +# "[Contributor] elects to include this software in this distribution +# under the [CDDL or GPL Version 2] license." If you do not indicate a +# single choice of license, a recipient has the option to distribute +# your version of this file under either the CDDL, the GPL Version 2 or +# to extend the choice of license to its licensees as provided above. +# However, if you add GPL Version 2 code and therefore, elected the GPL +# Version 2 license, then the option applies only if the new code is +# made subject to such option by the copyright holder. + +release.external/org.eclipse.osgi_3.6.0.v20100517.jar=modules/ext/org.eclipse.osgi_3.6.0.v20100517.jar +javac.source=1.6 +javac.compilerargs=-Xlint -Xlint:-serial diff -r 5cee832cf3ae netbinox/nbproject/project.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/nbproject/project.xml Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,93 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.modules.netbinox + + + org.netbeans.core.netigso + + + + 1.4.2 + + + + org.netbeans.libs.osgi + + + + 1.0 + + + + org.openide.modules + + + + 7.11 + + + + org.openide.util.lookup + + + + 8.0.0.1 + + + + + + unit + + org.netbeans.core.netigso + + + + + org.netbeans.libs.junit4 + + + + org.netbeans.modules.nbjunit + + + + + + + org.eclipse.core.runtime.adaptor + org.eclipse.osgi.baseadaptor + org.eclipse.osgi.baseadaptor.bundlefile + org.eclipse.osgi.baseadaptor.hooks + org.eclipse.osgi.baseadaptor.loader + org.eclipse.osgi.event + org.eclipse.osgi.framework.adaptor + org.eclipse.osgi.framework.console + org.eclipse.osgi.framework.debug + org.eclipse.osgi.framework.eventmgr + org.eclipse.osgi.framework.log + org.eclipse.osgi.framework.util + org.eclipse.osgi.service.datalocation + org.eclipse.osgi.service.debug + org.eclipse.osgi.service.environment + org.eclipse.osgi.service.internal.composite + org.eclipse.osgi.service.localization + org.eclipse.osgi.service.pluginconversion + org.eclipse.osgi.service.resolver + org.eclipse.osgi.service.runnable + org.eclipse.osgi.service.security + org.eclipse.osgi.service.urlconversion + org.eclipse.osgi.signedcontent + org.eclipse.osgi.storagemanager + org.eclipse.osgi.util + + + ext/org.eclipse.osgi_3.6.0.v20100517.jar + external/org.eclipse.osgi_3.6.0.v20100517.jar + + + + diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/Bundle.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/Bundle.properties Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,18 @@ +# +# Copyright (C) 2009 Jaroslav Tulach +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; version 2 +# of the License. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +OpenIDE-Module-Name=Netigso Equinox Integration diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/EmptyBundleFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/EmptyBundleFile.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Enumeration; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; + +/** + * + * @author Jaroslav Tulach + */ +final class EmptyBundleFile extends BundleFile { + public static final BundleFile EMPTY = new EmptyBundleFile(); + + private EmptyBundleFile() { + } + + @Override + public File getFile(String string, boolean bln) { + return null; + } + + @Override + public BundleEntry getEntry(String string) { + return null; + } + + @Override + public Enumeration getEntryPaths(String string) { + return Collections.enumeration(Collections.emptyList()); + } + + @Override + public void close() throws IOException { + } + + @Override + public void open() throws IOException { + } + + @Override + public boolean containsDir(String string) { + return false; + } +} diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/JarBundleFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/JarBundleFile.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.eclipse.osgi.baseadaptor.bundlefile.DirBundleFile; +import org.eclipse.osgi.baseadaptor.bundlefile.MRUBundleFileList; +import org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleFile; +import org.netbeans.core.netigso.spi.BundleContent; +import org.netbeans.core.netigso.spi.NetigsoArchive; + +/** This is fake bundle. It is created by the Netbinox infrastructure to + * use the {@link NetigsoArchive} to get cached data and speed up the start. + * + * @author Jaroslav Tulach + */ +final class JarBundleFile extends BundleFile implements BundleContent { + private BundleFile delegate; + + private static Map usedIds; + + private final MRUBundleFileList mru; + private final BaseData data; + private final NetigsoArchive archive; + + JarBundleFile( + File base, BaseData data, NetigsoArchive archive, + MRUBundleFileList mru, boolean isBase + ) { + super(base); + + long id; + if (isBase) { + id = data.getBundleID(); + } else { + id = 100000 + base.getPath().hashCode(); + } + + boolean assertOn = false; + assert assertOn = true; + if (assertOn) { + if (usedIds == null) { + usedIds = new HashMap(); + } + File prev = usedIds.put(id, base); + if (prev != null && !prev.equals(base)) { + NetbinoxFactory.LOG.log( + Level.WARNING, + "same id: {0} for {1} and {2}", // NOI18N + new Object[]{id, base, prev} + ); + } + } + + this.archive = archive.forBundle(id, this); + this.data = data; + this.mru = mru; + } + + + private synchronized BundleFile delegate(String who, String what) { + if (delegate == null) { + NetbinoxFactory.LOG.log(Level.FINE, "opening {0} because of {1} needing {2}", new Object[]{data.getLocation(), who, what}); + try { + delegate = new ZipBundleFile(getBaseFile(), data, mru) { + @Override + protected boolean checkedOpen() { + try { + return getZipFile() != null; + } catch (IOException ex) { + final File bf = new File(getBaseFile().getPath()); + if (bf.isDirectory()) { + try { + delegate = new DirBundleFile(bf); + return false; + } catch (IOException dirEx) { + NetbinoxFactory.LOG.log(Level.WARNING, + "Cannot create DirBundleFile for " + bf, + dirEx + ); + } + } + NetbinoxFactory.LOG.log(Level.WARNING, "Cannot open file {0}", bf); + if (!bf.isFile() || !bf.canRead()) { + delegate = EmptyBundleFile.EMPTY; + return false; + } + } + // no optimizations + return super.checkedOpen(); + } + }; + } catch (IOException ex) { + NetbinoxFactory.LOG.log(Level.FINE, "Error creating delegate for {0}", getBaseFile()); + delegate = EmptyBundleFile.EMPTY; + } + } + return delegate; + } + + @Override + public File getBaseFile() { + final File file = super.getBaseFile(); + class VFile extends File { + + public VFile() { + super(file.getPath()); + } + + @Override + public boolean isDirectory() { + return false; + } + + @Override + public File getAbsoluteFile() { + return this; + } + } + return new VFile(); + } + + @Override + public File getFile(String file, boolean bln) { + byte[] exists = getCachedEntry(file); + if (exists == null) { + return null; + } + BundleFile d = delegate("getFile", file); + return d == null ? null : d.getFile(file, bln); + } + + public byte[] resource(String name) throws IOException { + BundleEntry u = findEntry("resource", name); + if (u == null) { + return null; + } + InputStream is = u.getInputStream(); + if (is == null) { + return new byte[0]; + } + byte[] arr = null; + try { + arr = new byte[is.available()]; + int pos = 0; + for (;;) { + int toRead = arr.length - pos; + if (toRead == 0) { + break; + } + int len = is.read(arr, pos, toRead); + if (len == -1) { + break; + } + pos += len; + } + if (pos != arr.length) { + throw new IOException("Not read enough: " + pos + " should have been: " + arr.length); // NOI18N + } + } finally { + is.close(); + } + return arr; + } + + private BundleEntry findEntry(String why, String name) { + BundleEntry u; + for (;;) { + BundleFile d = delegate(why, name); + u = d.getEntry(name); + if (u != null || d == delegate) { + break; + } + } + return u; + } + + + private byte[] getCachedEntry(String name) { + try { + return archive.fromArchive(name); + } catch (IOException ex) { + return null; + } + } + + @Override + public BundleEntry getEntry(final String name) { + final byte[] arr = getCachedEntry(name); + if (arr == null && !name.equals("/")) { + return null; + } + return new BundleEntry() { + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(arr); + } + + @Override + public long getSize() { + return arr.length; + } + + @Override + public String getName() { + return name; + } + + @Override + public long getTime() { + return getBaseFile().lastModified(); + } + + @Override + public URL getLocalURL() { + return findEntry("getLocalURL", name).getLocalURL(); // NOI18N + } + + @Override + public URL getFileURL() { + return findEntry("getFileURL", name).getFileURL(); // NOI18N + } + }; + } + + @Override + public Enumeration getEntryPaths(String prefix) { + BundleFile d = delegate("getEntryPaths", prefix); + if (d == null) { + return Collections.enumeration(Collections.emptyList()); + } + return d.getEntryPaths(prefix); + } + + @Override + public synchronized void close() throws IOException { + if (delegate != null) { + delegate.close(); + } + } + + @Override + public void open() throws IOException { + if (delegate != null) { + delegate.open(); + } + } + + @Override + public boolean containsDir(String path) { + return path.endsWith("/") && getEntry(path) != null; + } +} diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/Netbinox.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/Netbinox.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2009-2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.Dictionary; +import java.util.Map; +import java.util.Properties; +import org.eclipse.osgi.framework.internal.core.FrameworkProperties; +import org.eclipse.osgi.launch.Equinox; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.BundleListener; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkListener; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +/** + * + * @author Jaroslav Tulach + */ +class Netbinox extends Equinox { + public Netbinox(Map configuration) { + super(configuration); + } + + @Override + public void init() throws BundleException { + super.init(); + if (Boolean.getBoolean("osgi.framework.useSystemProperties")) { + Properties prev = FrameworkProperties.getProperties(); + try { + Field f = FrameworkProperties.class.getDeclaredField("properties"); // NOI18N + f.setAccessible(true); + f.set(null, null); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + Properties newP = FrameworkProperties.getProperties(); + for (Map.Entry en : prev.entrySet()) { + if (en.getKey() instanceof String && en.getValue() instanceof String) { + newP.setProperty((String)en.getKey(), (String)en.getValue()); + } + } + assert System.getProperties() == FrameworkProperties.getProperties(); + } + } + + + + @Override + public BundleContext getBundleContext() { + return new Context(super.getBundleContext()); + } + + private static final class Context implements BundleContext { + private final BundleContext delegate; + + public Context(BundleContext delegate) { + this.delegate = delegate; + } + + public boolean ungetService(ServiceReference sr) { + return delegate.ungetService(sr); + } + + public void removeServiceListener(ServiceListener sl) { + delegate.removeServiceListener(sl); + } + + public void removeFrameworkListener(FrameworkListener fl) { + delegate.removeFrameworkListener(fl); + } + + public void removeBundleListener(BundleListener bl) { + delegate.removeBundleListener(bl); + } + + public ServiceRegistration registerService(String string, Object o, Dictionary dctnr) { + return delegate.registerService(string, o, dctnr); + } + + public ServiceRegistration registerService(String[] strings, Object o, Dictionary dctnr) { + return delegate.registerService(strings, o, dctnr); + } + + public Bundle installBundle(String string) throws BundleException { + return installBundle(string, null); + } + + public Bundle installBundle(String url, InputStream in) throws BundleException { + if (url.startsWith("reference:")) { + // workaround for problems with space in path + url = url.replaceAll("%20", " "); + } + return delegate.installBundle(url, in); + } + + public ServiceReference[] getServiceReferences(String string, String string1) throws InvalidSyntaxException { + return delegate.getServiceReferences(string, string1); + } + + public ServiceReference getServiceReference(String string) { + return delegate.getServiceReference(string); + } + + public Object getService(ServiceReference sr) { + return delegate.getService(sr); + } + + public String getProperty(String string) { + return delegate.getProperty(string); + } + + public File getDataFile(String string) { + return delegate.getDataFile(string); + } + + public Bundle[] getBundles() { + return delegate.getBundles(); + } + + public Bundle getBundle(long l) { + return delegate.getBundle(l); + } + + public Bundle getBundle() { + return delegate.getBundle(); + } + + public ServiceReference[] getAllServiceReferences(String string, String string1) throws InvalidSyntaxException { + return delegate.getAllServiceReferences(string, string1); + } + + public Filter createFilter(String string) throws InvalidSyntaxException { + return delegate.createFilter(string); + } + + public void addServiceListener(ServiceListener sl) { + delegate.addServiceListener(sl); + } + + public void addServiceListener(ServiceListener sl, String string) throws InvalidSyntaxException { + delegate.addServiceListener(sl, string); + } + + public void addFrameworkListener(FrameworkListener fl) { + delegate.addFrameworkListener(fl); + } + + public void addBundleListener(BundleListener bl) { + delegate.addBundleListener(bl); + } + } // end of Context +} diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/NetbinoxFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/NetbinoxFactory.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; +import org.eclipse.osgi.launch.EquinoxFactory; +import org.netbeans.core.netigso.spi.NetigsoArchive; +import org.openide.util.lookup.ServiceProvider; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; +import org.osgi.framework.launch.Framework; +import org.osgi.framework.launch.FrameworkFactory; + +/** + * + * @author Jaroslav Tulach + */ +@ServiceProvider( + service=FrameworkFactory.class, + supersedes={ "org.eclipse.osgi.launch.EquinoxFactory" }, + position=-10 +) +public class NetbinoxFactory implements FrameworkFactory { + static final Logger LOG = Logger.getLogger("org.netbeans.modules.netbinox"); // NOI18N + + @SuppressWarnings("unchecked") + public Framework newFramework(Map map) { + Map configMap = new HashMap(); + configMap.putAll(map); + configMap.put("osgi.hook.configurators.exclude", // NOI18N + "org.eclipse.core.runtime.internal.adaptor.EclipseLogHook" // NOI18N +// + ",org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook" // NOI18N + ); + configMap.put("osgi.hook.configurators.include", NetbinoxHooks.class.getName()); // NOI18N + configMap.put("osgi.user.area.default", configMap.get(Constants.FRAMEWORK_STORAGE)); // NOI18N + configMap.put("osgi.instance.area.default", System.getProperty("netbeans.user")); // NOI18N + configMap.put("osgi.install.area", System.getProperty("netbeans.home")); // NOI18N + // some useless value + configMap.put("osgi.framework.properties", System.getProperty("netbeans.user")); // NOI18N + + Object rawBundleMap = configMap.get("felix.bootdelegation.classloaders"); // NOI18N + + Map bundleMap; + if (rawBundleMap == null) { + bundleMap = null; + } else { + bundleMap = (Map)rawBundleMap; + } + + NetbinoxHooks.registerMap(bundleMap); + NetbinoxHooks.registerArchive((NetigsoArchive)configMap.get("netigso.archive")); // NOI18N + + String loc = EquinoxFactory.class.getProtectionDomain().getCodeSource().getLocation().toExternalForm(); + int file = loc.indexOf("file:"); + if (file > 0) { + loc = loc.substring(file); + } + int exclaim = loc.indexOf("!"); + if (exclaim > 0) { + loc = loc.substring(0, exclaim); + } + configMap.put("osgi.framework", loc); + return new Netbinox(configMap); + } +} diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/NetbinoxHooks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/NetbinoxHooks.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.IOException; +import java.io.Writer; +import java.net.URL; +import java.net.URLConnection; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import org.eclipse.osgi.baseadaptor.BaseAdaptor; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.baseadaptor.HookConfigurator; +import org.eclipse.osgi.baseadaptor.HookRegistry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.eclipse.osgi.baseadaptor.bundlefile.MRUBundleFileList; +import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook; +import org.eclipse.osgi.baseadaptor.hooks.BundleFileFactoryHook; +import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook; +import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader; +import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry; +import org.eclipse.osgi.baseadaptor.loader.ClasspathManager; +import org.eclipse.osgi.framework.adaptor.BundleData; +import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain; +import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate; +import org.eclipse.osgi.framework.log.FrameworkLog; +import org.eclipse.osgi.framework.log.FrameworkLogEntry; +import org.netbeans.core.netigso.spi.NetigsoArchive; +import org.openide.util.Lookup; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.FrameworkEvent; + +/** + * + * @author Jaroslav Tulach + */ +public final class NetbinoxHooks implements HookConfigurator, ClassLoadingHook, +BundleFileFactoryHook, FrameworkLog, AdaptorHook { + private static transient Map map; + private static transient NetigsoArchive archive; + static void clear() { + map = null; + archive = null; + } + + static void registerMap(Map bundleMap) { + map = bundleMap; + } + + static void registerArchive(NetigsoArchive netigsoArchive) { + archive = netigsoArchive; + } + + public void addHooks(HookRegistry hr) { + hr.addClassLoadingHook(this); + hr.addBundleFileFactoryHook(this); + hr.addAdaptorHook(this); + for (HookConfigurator hc : Lookup.getDefault().lookupAll(HookConfigurator.class)) { + hc.addHooks(hr); + } + } + + public byte[] processClass(String string, byte[] bytes, ClasspathEntry ce, BundleEntry be, ClasspathManager cm) { + return bytes; + } + + public boolean addClassPathEntry(ArrayList al, String string, ClasspathManager cm, BaseData bd, ProtectionDomain pd) { + return false; + } + + public String findLibrary(BaseData bd, String string) { + return null; + } + + public ClassLoader getBundleClassLoaderParent() { + return null; + } + + public BaseClassLoader createClassLoader(ClassLoader parent, final ClassLoaderDelegate delegate, final BundleProtectionDomain bpd, BaseData bd, String[] classpath) { + String loc = bd.getBundle().getLocation(); + //NetigsoModule.LOG.log(Level.FINER, "createClassLoader {0}", bd.getLocation()); + final String pref = "netigso://"; // NOI18N + ClassLoader ml = null; + if (loc != null && loc.startsWith(pref)) { + String cnb = loc.substring(pref.length()); + ml = map.get(bd.getBundle()); + } + if (ml == null) { + return new NetbinoxLoader(parent, delegate, bpd, bd, classpath); + } + class Del extends ClassLoader implements BaseClassLoader { + public Del(ClassLoader parent) { + super(parent); + } + + public ProtectionDomain getDomain() { + return bpd; + } + + public ClasspathEntry createClassPathEntry(BundleFile bf, ProtectionDomain pd) { + return null; + } + + public Class defineClass(String string, byte[] bytes, ClasspathEntry ce, BundleEntry be) { + throw new UnsupportedOperationException(); + } + + public Class publicFindLoaded(String name) { + return super.findLoadedClass(name); + } + + public Object publicGetPackage(String name) { + return super.getPackage(name); + } + + public Object publicDefinePackage(String s1, String s2, String s3, String s4, String s5, String s6, String s7, URL url) { + return super.definePackage(s1, s2, s3, s4, s5, s6, s7, url); + } + + public ClasspathManager getClasspathManager() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void initialize() { + } + + public URL findLocalResource(String name) { + return null; + /* + ProxyClassLoader pcl = (ProxyClassLoader)getParent(); + return pcl.findResource(name); + * + */ + } + + public Enumeration findLocalResources(String name) { + return null; + /* + ProxyClassLoader pcl = (ProxyClassLoader)getParent(); + try { + return pcl.findResources(name); + } catch (IOException ex) { + return Enumerations.empty(); + } + */ + } + + @Override + protected URL findResource(String name) { + return findLocalResource(name); + } + + @Override + protected Enumeration findResources(String name) throws IOException { + return findLocalResources(name); + } + + public Class findLocalClass(String name) throws ClassNotFoundException { + return getParent().loadClass(name); + } + + public void close() { + } + + public void attachFragment(BundleData bd, ProtectionDomain pd, String[] strings) { + } + + public ClassLoaderDelegate getDelegate() { + return delegate; + } + + public Bundle getBundle() { + throw new UnsupportedOperationException("Not supported yet."); + } + } + return new Del(ml); + } + + public void initializedClassLoader(BaseClassLoader bcl, BaseData bd) { + } + + private final MRUBundleFileList mruList = new MRUBundleFileList(); + public BundleFile createBundleFile(Object file, final BaseData bd, boolean isBase) throws IOException { + + if (file instanceof File) { + final File f = (File)file; +// running with fake manifest fails for some reason, disabling for now +// final String loc = bd.getLocation(); +// if (loc != null && loc.startsWith("netigso://")) { +// return new NetigsoBundleFile(f, bd); +// } + return new JarBundleFile(f, bd, archive, mruList, isBase); + } + return null; + } + + public void log(FrameworkEvent fe) { + Level l = Level.FINE; + if ((fe.getType() & FrameworkEvent.ERROR) != 0) { + l = Level.SEVERE; + } else if ((fe.getType() & FrameworkEvent.WARNING) != 0) { + l = Level.WARNING; + } else if ((fe.getType() & FrameworkEvent.INFO) != 0) { + l = Level.INFO; + } + LogRecord lr = new LogRecord(l, "framework event {0} type {1}"); + lr.setParameters(new Object[]{fe.getBundle().getSymbolicName(), fe.getType()}); + lr.setThrown(fe.getThrowable()); + lr.setLoggerName(NetbinoxFactory.LOG.getName()); + NetbinoxFactory.LOG.log(lr); + } + + public void log(FrameworkLogEntry fle) { + NetbinoxFactory.LOG.log(Level.FINE, "entry {0}", fle); + } + + public void setWriter(Writer writer, boolean bln) { + } + + public void setFile(File file, boolean bln) throws IOException { + } + + public File getFile() { + return null; + } + + public void setConsoleLog(boolean bln) { + } + + public void close() { + } + + // adaptor hooks + + public void initialize(BaseAdaptor ba) { + } + + public void frameworkStart(BundleContext bc) throws BundleException { + } + + public void frameworkStop(BundleContext bc) throws BundleException { + } + + public void frameworkStopping(BundleContext bc) { + } + + public void addProperties(Properties prprts) { + } + + public URLConnection mapLocationToURLConnection(String string) throws IOException { + return null; + } + + public void handleRuntimeError(Throwable thrwbl) { + NetbinoxFactory.LOG.log(Level.WARNING, thrwbl.getMessage(), thrwbl); + } + + public FrameworkLog createFrameworkLog() { + return this; + } +} diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/NetbinoxLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/NetbinoxLoader.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.ProtectionDomain; +import java.util.logging.Level; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader; +import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry; +import org.eclipse.osgi.baseadaptor.loader.ClasspathManager; +import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate; +import org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader; +import org.osgi.framework.FrameworkEvent; + +/** Classloader that eliminates some unnecessary disk touches. + * + * @author Jaroslav Tulach + */ +final class NetbinoxLoader extends DefaultClassLoader { + public NetbinoxLoader(ClassLoader parent, ClassLoaderDelegate delegate, ProtectionDomain domain, BaseData bd, String[] classpath) { + super(parent, delegate, domain, bd, classpath); + this.manager = new NoTouchCPM(bd, classpath, this); + } + + @Override + public String toString() { + return "NetbinoxLoader delegating to " + delegate; + } + + private static class NoTouchCPM extends ClasspathManager { + public NoTouchCPM(BaseData data, String[] classpath, BaseClassLoader classloader) { + super(data, classpath, classloader); + } + + @Override + public ClasspathEntry getClasspath(String cp, BaseData sourcedata, ProtectionDomain sourcedomain) { + BundleFile bundlefile = null; + File file; + BundleEntry cpEntry = sourcedata.getBundleFile().getEntry(cp); + // check for internal library directories in a bundle jar file + if (cpEntry != null && cpEntry.getName().endsWith("/")) //$NON-NLS-1$ + { + bundlefile = createBundleFile(cp, sourcedata); + } // check for internal library jars + else if ((file = sourcedata.getBundleFile().getFile(cp, false)) != null) { + bundlefile = createBundleFile(file, sourcedata); + } + if (bundlefile != null) { + return createClassPathEntry(bundlefile, sourcedomain, sourcedata); + } + return null; + } + + @Override + public ClasspathEntry getExternalClassPath(String cp, BaseData sourcedata, ProtectionDomain sourcedomain) { + File file; + if (cp.startsWith("file:")) { // NOI18N + try { + file = new File(new URI(cp)); + } catch (URISyntaxException ex) { + NetbinoxFactory.LOG.log(Level.SEVERE, "Cannot convert to file: " + cp, ex); // NOI18N + return null; + } + } else { + file = new File(cp); + } + if (!file.isAbsolute() && !cp.startsWith("file:")) { // NOI18N + return null; + } + BundleFile bundlefile = createBundleFile(file, sourcedata); + if (bundlefile != null) { + return createClassPathEntry(bundlefile, sourcedomain, sourcedata); + } + return null; + } + + private static BundleFile createBundleFile(Object content, BaseData sourcedata) { + try { + return sourcedata.getAdaptor().createBundleFile(content, sourcedata); + } catch (IOException e) { + sourcedata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, sourcedata.getBundle(), e); + } + return null; + } + private ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain cpDomain, final BaseData data) { + return new ClasspathEntry(bundlefile, createProtectionDomain(bundlefile, cpDomain)) { + @Override + public BaseData getBaseData() { + return data; + } + }; + } + } // end of NoTouchCPM +} diff -r 5cee832cf3ae netbinox/src/org/netbeans/modules/netbinox/NetigsoBundleFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/src/org/netbeans/modules/netbinox/NetigsoBundleFile.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.jar.Manifest; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.eclipse.osgi.framework.adaptor.BundleData; +import org.openide.modules.ModuleInfo; +import org.openide.util.Lookup; + +/** This is fake bundle, created by the Netigso infrastructure. + * + * @author Jaroslav Tulach + */ +final class NetigsoBundleFile extends BundleFile { + private final BundleData data; + NetigsoBundleFile(File base, BundleData data) { + super(base); + this.data = data; + } + + @Override + public File getFile(String string, boolean bln) { + return null; + } + + @Override + public BundleEntry getEntry(String entry) { + if ("META-INF/MANIFEST.MF".equals(entry)) { // NOI18N + return new BundleEntry() { + @Override + public InputStream getInputStream() throws IOException { + for (ModuleInfo mi : Lookup.getDefault().lookupAll(ModuleInfo.class)) { + if (data.getLocation().endsWith(mi.getCodeNameBase())) { + return fakeManifest(mi); + } + } + throw new IOException("Cannot find " + data.getLocation()); + } + + @Override + public long getSize() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getName() { + return "META-INF/MANIFEST.MF"; // NOI18N + } + + @Override + public long getTime() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public URL getLocalURL() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public URL getFileURL() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + } + return null; + } + + @Override + public Enumeration getEntryPaths(String string) { + return Collections.enumeration(Collections.emptyList()); + } + + @Override + public void close() throws IOException { + } + + @Override + public void open() throws IOException { + } + + @Override + public boolean containsDir(String string) { + return false; + } + + private static InputStream fakeManifest(ModuleInfo m) throws IOException { + String exp = (String) m.getAttribute("OpenIDE-Module-Public-Packages"); // NOI18N + if ("-".equals(exp)) { // NOI18N + return null; + } + ByteArrayOutputStream os = new ByteArrayOutputStream(); + Manifest man = new Manifest(); + man.getMainAttributes().putValue("Manifest-Version", "1.0"); // workaround for JDK bug + man.getMainAttributes().putValue("Bundle-ManifestVersion", "2"); // NOI18N + man.getMainAttributes().putValue("Bundle-SymbolicName", m.getCodeNameBase()); // NOI18N + + if (m.getSpecificationVersion() != null) { + String spec = threeDotsWithMajor(m.getSpecificationVersion().toString(), m.getCodeName()); + man.getMainAttributes().putValue("Bundle-Version", spec.toString()); // NOI18N + } + if (exp != null) { + man.getMainAttributes().putValue("Export-Package", exp.replaceAll("\\.\\*", "")); // NOI18N + } else { + man.getMainAttributes().putValue("Export-Package", m.getCodeNameBase()); // NOI18N + } + man.write(os); + return new ByteArrayInputStream(os.toByteArray()); + } + private static String threeDotsWithMajor(String version, String withMajor) { + int indx = withMajor.indexOf('/'); + int major = 0; + if (indx > 0) { + major = Integer.parseInt(withMajor.substring(indx + 1)); + } + String[] segments = (version + ".0.0.0").split("\\."); + assert segments.length >= 3 && segments[0].length() > 0; + + return (Integer.parseInt(segments[0]) + major * 100) + "." + segments[1] + "." + segments[2]; + } +} diff -r 5cee832cf3ae netbinox/test/unit/data/jars/activate.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/activate.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-SymbolicName: org.activate +Bundle-Version: 1.2 +Import-Package: org.osgi.framework +Bundle-Activator: org.activate.Main +OpenIDE-Module-Layer: org/activate/layer.xml + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/activate/org/activate/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/activate/org/activate/Main.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,85 @@ +package org.activate; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Main implements BundleActivator { + public static BundleContext start; + public static BundleContext stop; + public static ClassLoader loader; + private static final Logger LOG = Logger.getLogger(Main.class.getName()); + + public void start(BundleContext bc) throws Exception { + LOG.log(Level.INFO, "start {0}", bc); + assert start == null; + start = bc; + final String v = System.getProperty("activated.count"); + if (v != null) { + int x = Integer.parseInt(v); + System.setProperty("activated.count", "" + (x + 1)); + } + System.setProperty("activated.ok", "true"); + loader = Thread.currentThread().getContextClassLoader(); + String t = System.getProperty("activated.throw"); + if (t != null) { + LOG.log(Level.INFO, "Throwing exception {0}", t); + throw new IllegalStateException(t); + } + LOG.info("start finished"); + + String lib = System.getProperty("activated.library"); + if (lib != null) { + try { + System.loadLibrary(lib); + throw new IllegalStateException("Library " + lib + " should not be available"); + } catch (UnsatisfiedLinkError ex) { + System.setProperty("activated.library", ex.getMessage()); + } + } + + + String seekFor = System.getProperty("activated.checkentries"); + if (seekFor != null) { + LOG.info("loading bundleentry:"); + URL u = getClass().getResource(seekFor); + assert "bundleresource".equals(u.getProtocol()) : "Protocol: " + u.getProtocol(); + BufferedReader r = new BufferedReader(new InputStreamReader(u.openStream())); + String c = r.readLine(); + r.close(); + System.setProperty("activated.entry", c); + LOG.log(Level.INFO, "entry loaded: {0}", c); + + URLConnection buc = u.openConnection(); + System.setProperty("activated.entry.local", ((URL)call(buc, "getLocalURL")).toExternalForm()); + System.setProperty("activated.entry.file", ((URL)call(buc, "getFileURL")).toExternalForm()); + + LOG.log(Level.INFO, "BundleURLConnection is OK"); + } + } + + public void stop(BundleContext bc) throws Exception { + LOG.log(Level.INFO, "stop {0}", bc); + assert stop == null; + stop = bc; + } + + private static Object call(Object obj, String name) throws Exception { + Class c = obj.getClass(); + return c.getMethod(name).invoke(obj); + } + + public static Class loadClass(String name, ClassLoader ldr) throws ClassNotFoundException { + LOG.log(Level.INFO, "Trying to load from {0} class named: {1}", new Object[]{ldr, name}); + if (ldr == null) { + return Class.forName(name); + } + return Class.forName(name, true, ldr); + } +} + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/activate/org/activate/entry.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/activate/org/activate/entry.txt Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,1 @@ +Ahoj diff -r 5cee832cf3ae netbinox/test/unit/data/jars/activate/org/activate/layer.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/activate/org/activate/layer.xml Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,4 @@ + + + + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/depends-on-simple-module-2.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/depends-on-simple-module-2.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.bar2/1 +OpenIDE-Module-Name: Depends on foo test module #2 +OpenIDE-Module-Module-Dependencies: org.foo/1 + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/depends-on-simple-module.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/depends-on-simple-module.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.bar/1 +OpenIDE-Module-Name: Depends on foo test module +OpenIDE-Module-Module-Dependencies: org.foo/1 + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/depends-on-simple-module/org/bar/SomethingElse.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/depends-on-simple-module/org/bar/SomethingElse.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,7 @@ +package org.bar; +import org.foo.Something; +public class SomethingElse extends Something { + public String message() { + return something(); + } +} diff -r 5cee832cf3ae netbinox/test/unit/data/jars/depends-on-simple-module/org/bar/impl/layer.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/depends-on-simple-module/org/bar/impl/layer.xml Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,47 @@ + + + + + + + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/depends-on-simple-module/org/bar/layer.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/depends-on-simple-module/org/bar/layer.xml Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,47 @@ + + + + + + + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/external.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/external.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-SymbolicName: org.external +Bundle-Version: 2.33 +Import-Package: org.osgi.framework +Bundle-Activator: org.activate.Main +OpenIDE-Module-Layer: org/activate/layer.xml +Bundle-ClassPath: external:$ext.dir$/ext.jar + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/externaldir.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/externaldir.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-SymbolicName: org.externaldir +Bundle-Version: 2.33 +Import-Package: org.osgi.framework +Bundle-Activator: org.activate.Main +OpenIDE-Module-Layer: org/activate/layer.xml +Bundle-ClassPath: external:$ext.dir$/activate/ + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/hook.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/hook.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.hook +OpenIDE-Module-Module-Dependencies: org.netbeans.modules.netbinox > 1.16.7 +OpenIDE-Module-Specification-Version: 1.2 +OpenIDE-Module-Public-Packages: - diff -r 5cee832cf3ae netbinox/test/unit/data/jars/hook/org/hook/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/hook/org/hook/Main.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,14 @@ +package org.activate; + +import org.eclipse.osgi.baseadaptor.HookConfigurator; +import org.eclipse.osgi.baseadaptor.HookRegistry; +import org.openide.util.lookup.ServiceProvider; + +@ServiceProvider(service=HookConfigurator.class) +public class Main implements HookConfigurator { + public void addHooks(HookRegistry hr) { + assert hr != null; + System.setProperty("main.hook", "true"); + } +} + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/simple-module.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/simple-module.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.foo/1 +OpenIDE-Module-Name: Foo test module +OpenIDE-Module-Specification-Version: 1.2 + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/simple-module/org/foo/Something.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/simple-module/org/foo/Something.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,20 @@ +package org.foo; +// Does not do anything, just needs to be here & loadable. + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Something { + protected String something() { + return "hello"; + } + + private static final Logger LOG = Logger.getLogger(Something.class.getName()); + public static Class loadClass(String name, ClassLoader ldr) throws ClassNotFoundException { + LOG.log(Level.INFO, "Trying to load from {0} class named: {1}", new Object[]{ldr, name}); + if (ldr == null) { + return Class.forName(name); + } + return Class.forName(name, true, ldr); + } +} diff -r 5cee832cf3ae netbinox/test/unit/data/jars/uses-swing.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/uses-swing.mf Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-SymbolicName: org.barwing +Bundle-Version: 1.2 +Import-Package: javax.swing + + diff -r 5cee832cf3ae netbinox/test/unit/data/jars/uses-swing/org/barwing/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/data/jars/uses-swing/org/barwing/Main.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,8 @@ +package org.barwing; +import javax.swing.JFrame; +public class Main extends JFrame implements Runnable { + public void run() { + new Main().setVisible(true); + } +} + diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/MockEvents.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/MockEvents.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,27 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") (the + * "License"). You may not use this file except in compliance with the + * License. + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 2009 Sun + * Microsystems, Inc. All Rights Reserved. + * + * Jaroslav Tulach elects to include this software in this distribution + * under the GPL Version 2 license. + */ + +package org.netbeans; + +public final class MockEvents extends Events { + + protected void logged(String message, Object[] args) {} + +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/MockModuleInstaller.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/MockModuleInstaller.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,82 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") (the + * "License"). You may not use this file except in compliance with the + * License. + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 2009 Sun + * Microsystems, Inc. All Rights Reserved. + * + * Jaroslav Tulach elects to include this software in this distribution + * under the GPL Version 2 license. + */ + +package org.netbeans; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class MockModuleInstaller extends ModuleInstaller { + + // For examining results of what happened: + public final List actions = new ArrayList(); + public final List args = new ArrayList(); + + public void clear() { + actions.clear(); + args.clear(); + } + // For adding invalid modules: + public final Set delinquents = new HashSet(); + // For adding modules that don't want to close: + public final Set wontclose = new HashSet(); + + public void prepare(Module m) throws InvalidException { + if (delinquents.contains(m)) { + throw new InvalidException(m, "not supposed to be installed"); + } + actions.add("prepare"); + args.add(m); + } + + public void dispose(Module m) { + actions.add("dispose"); + args.add(m); + } + + public void load(List modules) { + actions.add("load"); + args.add(new ArrayList(modules)); + } + + public void unload(List modules) { + actions.add("unload"); + args.add(new ArrayList(modules)); + } + + public boolean closing(List modules) { + actions.add("closing"); + args.add(new ArrayList(modules)); + for (Module m : modules) { + if (wontclose.contains(m)) { + return false; + } + } + return true; + } + + public void close(List modules) { + actions.add("close"); + args.add(new ArrayList(modules)); + } + +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/SetupHid.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/SetupHid.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,436 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") (the + * "License"). You may not use this file except in compliance with the + * License. + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 2009 Sun + * Microsystems, Inc. All Rights Reserved. + * + * Jaroslav Tulach elects to include this software in this distribution + * under the GPL Version 2 license. + */ + +package org.netbeans; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.logging.Level; +import java.util.zip.CRC32; +import javax.tools.JavaCompiler; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import org.netbeans.junit.NbTestCase; + +/** Some infrastructure for module system tests. + * @author Jesse Glick + */ +public abstract class SetupHid extends NbTestCase { + + + public SetupHid(String name) { + super(name); + } + + /** directory of data files for JARs */ + protected File data; + /** directory full of JAR files to test */ + protected File jars; + /** shall the generated JARs have all dir entries? */ + protected static boolean generateAllDirs; + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + createTestJARs(); + + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + + System.setProperty("netbeans.user", ud.getPath()); + } + + @Override + protected Level logLevel() { + return Level.FINE; + } + + protected static void deleteRec(File f) throws IOException { + if (f.isDirectory()) { + File[] kids = f.listFiles(); + if (kids == null) throw new IOException("Could not list: " + f); + for (int i = 0; i < kids.length; i++) { + deleteRec(kids[i]); + } + } + if (! f.delete()) throw new IOException("Could not delete: " + f); + } + + /** same as FileUtil.copy */ + protected static void copyStreams(InputStream is, OutputStream os) throws IOException { + final byte[] BUFFER = new byte[4096]; + int len; + for (;;) { + len = is.read(BUFFER); + if (len == -1) { + return; + } + os.write(BUFFER, 0, len); + } + } + + protected static void copy(File a, File b) throws IOException { + OutputStream os = new FileOutputStream(b); + try { + copyStreams(new FileInputStream(a), os); + } finally { + os.close(); + } + } + + /** + * Create a fresh JAR file. + * @param jar the file to create + * @param contents keys are JAR entry paths, values are text contents (will be written in UTF-8) + * @param manifest a manifest to store (key/value pairs for main section) + */ + public static void createJar(File jar, Map contents, Map manifest) throws IOException { + // XXX use TestFileUtils.writeZipFile + Manifest m = new Manifest(); + m.getMainAttributes().putValue("Manifest-Version", "1.0"); // workaround for JDK bug + for (Map.Entry line : manifest.entrySet()) { + m.getMainAttributes().putValue(line.getKey(), line.getValue()); + } + jar.getParentFile().mkdirs(); + OutputStream os = new FileOutputStream(jar); + try { + JarOutputStream jos = new JarOutputStream(os, m); + Iterator it = contents.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + String path = (String) entry.getKey(); + byte[] data = ((String) entry.getValue()).getBytes("UTF-8"); + JarEntry je = new JarEntry(path); + je.setSize(data.length); + CRC32 crc = new CRC32(); + crc.update(data); + je.setCrc(crc.getValue()); + jos.putNextEntry(je); + jos.write(data); + } + jos.close(); + } finally { + os.close(); + } + } + + private void createTestJARs() throws IOException { + File simpleModule = createTestJAR("simple-module", null); + File dependsOnSimpleModule = createTestJAR("depends-on-simple-module", null, simpleModule); + createTestJAR("dep-on-dep-on-simple", null, simpleModule, dependsOnSimpleModule); + File cyclic1; + { // cyclic-1 + File cyclic1Src = new File(data, "cyclic-1"); + File cyclic2Src = new File(data, "cyclic-2"); + compile(Arrays.asList( + "-sourcepath", cyclic1Src + File.pathSeparator + cyclic2Src, + "-d", cyclic1Src.getAbsolutePath()), + findSourceFiles(cyclic1Src, cyclic2Src)); + cyclic1 = new File(jars, "cyclic-1.jar"); + OutputStream os = new FileOutputStream(cyclic1); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(new File(data, "cyclic-1.mf"))); + try { + jarUp(jos, new File(cyclic1Src, "org/foo"), "org/foo/"); + } finally { + jos.close(); + } + } finally { + os.close(); + } + } + File cyclic2 = createTestJAR("cyclic-2", null, cyclic1); + createTestJAR("depends-on-cyclic-1", null, cyclic1, cyclic2); + File libraryUndecl = createTestJAR("library-undecl", "library-src"); + createTestJAR("library-unvers", "library-src"); + createTestJAR("library-vers", "library-src"); + createTestJAR("library-vers-partial", "library-src"); + createTestJAR("depends-on-lib-undecl", "depends-on-library-src", libraryUndecl); + createTestJAR("depends-on-lib-unvers", "depends-on-library-src", libraryUndecl); + createTestJAR("depends-on-lib-vers", "depends-on-library-src", libraryUndecl); + createTestJAR("depends-on-lib-vers-partial", "depends-on-library-src", libraryUndecl); + createTestJAR("fails-on-lib-undecl", "depends-on-library-src", libraryUndecl); + createTestJAR("fails-on-non-existing-package", "depends-on-library-src", libraryUndecl); + createTestJAR("fails-on-lib-unvers", "depends-on-library-src", libraryUndecl); + createTestJAR("fails-on-lib-old", "depends-on-library-src", libraryUndecl); + createTestJAR("prov-foo", null); + createTestJAR("req-foo", null); + createTestJAR("prov-foo-bar", null); + createTestJAR("req-foo-baz", null); + createTestJAR("prov-baz", null); + createTestJAR("prov-foo-req-bar", null); + createTestJAR("prov-bar-req-foo", null); + createTestJAR("prov-bar-dep-cyclic", null); + createTestJAR("rel-ver-2", null); + createTestJAR("dep-on-relvertest-1", null); + createTestJAR("dep-on-relvertest-1-2", null); + createTestJAR("dep-on-relvertest-1-2-nospec", null); + createTestJAR("dep-on-relvertest-2", null); + createTestJAR("dep-on-relvertest-2-3", null); + createTestJAR("dep-on-relvertest-2-3-late", null); + createTestJAR("dep-on-relvertest-2-impl", null); + createTestJAR("dep-on-relvertest-2-impl-wrong", null); + createTestJAR("dep-on-relvertest-2-late", null); + createTestJAR("dep-on-relvertest-3-4", null); + createTestJAR("dep-on-relvertest-some", null); + createTestJAR("depends-on-simple-module-2", null); + createTestJAR("needs-foo", null); + createTestJAR("recommends-foo", null); + createTestJAR("prov-foo-depends-needs_foo", "prov-foo"); + createTestJAR("api-mod-export-all", "exposes-api"); + createTestJAR("api-mod-export-none", "exposes-api"); + File exposesAPI = createTestJAR("api-mod-export-api", "exposes-api"); + createTestJAR("api-mod-export-friend", "exposes-api"); + createTestJAR("uses-api-simple-dep", "uses-api", exposesAPI); + createTestJAR("uses-api-impl-dep", "uses-api", exposesAPI); + createTestJAR("uses-api-impl-dep-for-friends", "uses-api", exposesAPI); + createTestJAR("uses-api-spec-dep", "uses-api", exposesAPI); + createTestJAR("dep-on-two-modules", null); + File usesAPI = createTestJAR("uses-and-exports-api", "uses-api", exposesAPI); + createTestJAR("uses-api-transitively", null, exposesAPI, usesAPI); + createTestJAR("uses-api-directly", "uses-api-transitively", exposesAPI, usesAPI); + createTestJAR("uses-api-transitively-old", "uses-api-transitively", exposesAPI, usesAPI); + createTestJAR("uses-api-directly-old", "uses-api-transitively", exposesAPI, usesAPI); + createTestJAR("look-for-myself", null); + createTestJAR("uses-api-friend", "uses-api", exposesAPI); + createTestJAR("little-manifest", null); + createTestJAR("medium-manifest", null); + createTestJAR("big-manifest", null); + createTestJAR("patchable", null); + { // Make the patch JAR specially: + File src = new File(data, "patch"); + String srcS = src.getAbsolutePath(); + compile(Arrays.asList("-sourcepath", srcS, "-d", srcS), findSourceFiles(src)); + File jar = new File(jars, "patches/pkg-subpkg/some-patch.jar"); + jar.getParentFile().mkdirs(); + OutputStream os = new FileOutputStream(jar); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(null)); + try { + jarUp(jos, src, ""); + } finally { + jos.close(); + } + } finally { + os.close(); + } + } + File locale = new File(jars, "locale"); + locale.mkdirs(); + { + OutputStream os = new FileOutputStream(new File(jars, "localized-manifest.jar")); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(new File(data, "localized-manifest.mf"))); + try { + writeJarEntry(jos, "locmani/Bundle.properties", new File(data, "localized-manifest/locmani/Bundle.properties")); + } finally { + jos.close(); + } + } finally { + os.close(); + } + os = new FileOutputStream(new File(locale, "localized-manifest_cs.jar")); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(null)); + try { + writeJarEntry(jos, "locmani/Bundle_cs.properties", new File(data, "localized-manifest/locmani/Bundle_cs.properties")); + } finally { + jos.close(); + } + } finally { + os.close(); + } + } + { + OutputStream os = new FileOutputStream(new File(jars, "base-layer-mod.jar")); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(new File(data, "base-layer-mod.mf"))); + try { + writeJarEntry(jos, "baselayer/layer.xml", new File(data, "base-layer-mod/baselayer/layer.xml")); + } finally { + jos.close(); + } + } finally { + os.close(); + } + os = new FileOutputStream(new File(locale, "base-layer-mod_cs.jar")); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(null)); + try { + writeJarEntry(jos, "baselayer/layer_cs.xml", new File(data, "base-layer-mod/baselayer/layer_cs.xml")); + } finally { + jos.close(); + } + } finally { + os.close(); + } + os = new FileOutputStream(new File(locale, "base-layer-mod_foo.jar")); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(null)); + try { + writeJarEntry(jos, "baselayer/layer_foo.xml", new File(data, "base-layer-mod/baselayer/layer_foo.xml")); + } finally { + jos.close(); + } + } finally { + os.close(); + } + createTestJAR("override-layer-mod", null); + } + } + private static void compile(List options, Iterable files) throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager mgr = compiler.getStandardFileManager(null, null, null); + List fullOptions = new ArrayList(options); + fullOptions.addAll(Arrays.asList("-source", "1.5", "-target", "1.5")); + if (!compiler.getTask(null, mgr, null, fullOptions, null, mgr.getJavaFileObjectsFromFiles(files)).call()) { + throw new IOException("compilation failed"); + } + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } + public static File createTestJAR(File data, File jars, String name, String srcdir, File... classpath) throws IOException { + File srcdirF = null; + File d = new File(data, srcdir != null ? srcdir : name); + if (d.isDirectory()) { + srcdirF = d; + } + File manifestF = null; + File f = new File(data, name + ".mf"); + if (f.isFile()) { + manifestF = f; + } + if (srcdirF != null) { + assert srcdirF.isDirectory(); + List sourceFiles = findSourceFiles(srcdirF); + if (!sourceFiles.isEmpty()) { + StringBuilder cp = new StringBuilder(System.getProperty("java.class.path")); // o.o.util, o.o.modules + for (File j : classpath) { + cp.append(File.pathSeparatorChar); + cp.append(j); + } + compile(Arrays.asList( + "-classpath", cp.toString(), + "-sourcepath", srcdirF.getAbsolutePath(), + "-d", srcdirF.getAbsolutePath()), + sourceFiles); + } + } + // Cannot trivially use TestFileUtils.writeZipFile here since we have binary content (classes). + File jar = new File(jars, name + ".jar"); + jars.mkdirs(); + OutputStream os = new FileOutputStream(jar); + try { + JarOutputStream jos = new JarOutputStream(os, loadManifest(manifestF)); + try { + if (srcdirF != null) { + jarUp(jos, srcdirF, ""); + } + } finally { + jos.close(); + } + } finally { + os.close(); + } + return jar; + } + private static Manifest loadManifest(File mani) throws IOException { + Manifest m = new Manifest(); + if (mani != null) { + InputStream is = new FileInputStream(mani); + try { + m.read(is); + } finally { + is.close(); + } + } + m.getMainAttributes().putValue("Manifest-Version", "1.0"); // workaround for JDK bug + return m; + } + private static List findSourceFiles(File... roots) { + List sourceFiles = new ArrayList(); + for (File root : roots) { + doFindSourceFiles(sourceFiles, root); + } + return sourceFiles; + } + private static void doFindSourceFiles(List sourceFiles, File srcdir) { + for (File k : srcdir.listFiles()) { + if (k.getName().endsWith(".java")) { + sourceFiles.add(k); + } else if (k.isDirectory()) { + doFindSourceFiles(sourceFiles, k); + } + } + } + private static void jarUp(JarOutputStream jos, File dir, String prefix) throws IOException { + for (File f : dir.listFiles()) { + String path = prefix + f.getName(); + if (f.getName().endsWith(".java")) { + continue; + } else if (f.isDirectory()) { + if (generateAllDirs) { + JarEntry je = new JarEntry(path + "/"); + jos.putNextEntry(je); + } + jarUp(jos, f, path + "/"); + } else { + writeJarEntry(jos, path, f); + } + } + } + private static void writeJarEntry(JarOutputStream jos, String path, File f) throws IOException, FileNotFoundException { + JarEntry je = new JarEntry(path); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream is = new FileInputStream(f); + try { + copyStreams(is, baos); + } finally { + is.close(); + } + byte[] data = baos.toByteArray(); + je.setSize(data.length); + CRC32 crc = new CRC32(); + crc.update(data); + je.setCrc(crc.getValue()); + jos.putNextEntry(je); + jos.write(data); + } + +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/BundleURLConnectionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/BundleURLConnectionTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.awt.GraphicsEnvironment; +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.logging.Level; +import junit.framework.Test; +import org.netbeans.modules.netbinox.ContextClassLoaderTest.Compile; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.NetigsoFramework; +import org.netbeans.core.startup.Main; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.netbeans.junit.NbTestSuite; +import org.openide.util.Lookup; +import org.osgi.framework.Bundle; +import org.osgi.framework.launch.Framework; + +/** + * + * @author Jaroslav Tulach + */ +public class BundleURLConnectionTest extends NbTestCase { + static { + System.setProperty("java.awt.headless", "true"); + } + + public BundleURLConnectionTest(String name) { + super(name); + } + + public static Test suite() { + System.setProperty("java.awt.headless", "true"); + assertTrue("In headless mode", GraphicsEnvironment.isHeadless()); + NbTestSuite s = new NbTestSuite(); + s.addTest(new Compile("testCompileJAR")); + s.addTest(NbModuleSuite.create( + NbModuleSuite.emptyConfiguration().addTest( + BundleURLConnectionTest.class + ).honorAutoloadEager(true).failOnException(Level.WARNING)/*.failOnMessage(Level.WARNING)*/ + .gui(false) + )); + return s; + } + + public void testVariousURLs() throws Exception { + File j1 = new File(System.getProperty("activate.jar")); + assertTrue("File " + j1 + " exists", j1.exists()); + + ModuleManager mgr = Main.getModuleSystem().getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + Module m1; + m1 = mgr.create(j1, null, false, false, false); + System.setProperty("activated.checkentries", "/org/activate/entry.txt"); + mgr.enable(m1); + + assertTrue("OSGi module is now enabled", m1.isEnabled()); + mgr.mutexPrivileged().exitWriteAccess(); + + Object obj = Lookup.getDefault().lookup(NetigsoFramework.class); + final Method m = obj.getClass().getDeclaredMethod("getFramework"); + m.setAccessible(true); + Framework w = (Framework) m.invoke(obj); + assertNotNull("Framework found", w); + assertEquals("Felix is not in its name", -1, w.getClass().getName().indexOf("felix")); + StringBuilder sb = new StringBuilder(); + boolean found = false; + for (Bundle b : w.getBundleContext().getBundles()) { + sb.append("\n").append(b.getSymbolicName()); + if (b.getSymbolicName().equals("org.eclipse.osgi")) { + found = true; + break; + } + } + if (!found) { + fail("Expecting equinox among list of enabled bundles:" + sb); + } + String text = System.getProperty("activated.entry"); + assertEquals("Ahoj", text); + + + String localURL = System.getProperty("activated.entry.local"); + assertNotNull("bundleentry read OK", localURL); + // <[jar:file:/home/jarda/src/netbeans/netbinox/netbinox/build/test/unit/work/o.a.n.C/testCompileJAR/jars/activate.jar!/org/activate/entry.txt]> + assertEquals("Ahoj", readLine(localURL)); + + String fileURL = System.getProperty("activated.entry.file"); + assertNotNull("fileURL found", fileURL); + // file:/home/jarda/src/netbeans/netbinox/netbinox/build/test/unit/work/userdir0/var/cache/netigso/org.eclipse.osgi/bundles/46/1/.cp/org/activate/entry.txt + assertEquals("Ahoj", readLine(fileURL)); + } + + static String readLine(String url) throws Exception { + assertNotNull("url cannot be null", url); + URL u = new URL(url); + BufferedReader r = new BufferedReader(new InputStreamReader(u.openStream())); + return r.readLine(); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/CachingAndExternalPathsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/CachingAndExternalPathsTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,252 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import junit.framework.Test; +import org.netbeans.SetupHid; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.netbeans.junit.NbTestSuite; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileSystem; +import org.openide.filesystems.FileUtil; +import org.openide.util.Lookup; + +/** + * Read access test + * see details on http://wiki.netbeans.org/FitnessViaWhiteAndBlackList + */ +public class CachingAndExternalPathsTest extends NbTestCase { + static { + System.setProperty("java.awt.headless", "true"); + } + private static final Logger LOG = Logger.getLogger(CachingAndExternalPathsTest.class.getName()); + + private static void initCheckReadAccess() throws IOException { + Set allowedFiles = new HashSet(); + CountingSecurityManager.initialize(null, CountingSecurityManager.Mode.CHECK_READ, allowedFiles); + } + + public CachingAndExternalPathsTest(String name) { + super(name); + } + + public static Test suite() throws IOException { + return create(new SetExtDirProperty() { + public void setExtDirProperty(File value) { + System.setProperty("ext.dir", value.getPath()); + } + }); + } + static Test create(SetExtDirProperty setter) throws IOException { + Locale.setDefault(Locale.US); + CountingSecurityManager.initialize("none", CountingSecurityManager.Mode.CHECK_READ, null); + System.setProperty("org.netbeans.Stamps.level", "ALL"); + System.setProperty(NbModuleSuite.class.getName() + ".level", "FINE"); + System.setProperty("org.netbeans.modules.netbinox.level", "FINE"); + + NbTestSuite suite = new NbTestSuite(); + Compile compile = new Compile("testCompile", setter); + suite.addTest(compile); + NbModuleSuite.Configuration common = NbModuleSuite.emptyConfiguration().clusters(".*").enableClasspathModules(false) + .gui(false).honorAutoloadEager(true); + { + NbModuleSuite.Configuration conf = common.reuseUserDir(false).addTest(CachingAndExternalPathsTest.class, "testInitUserDir"); + suite.addTest(NbModuleSuite.create(conf)); + } + { + NbModuleSuite.Configuration conf = common.reuseUserDir(true).addTest(CachingAndExternalPathsTest.class, "testStartAgain"); + suite.addTest(NbModuleSuite.create(conf)); + } + + suite.addTest(new CachingAndExternalPathsTest("testInMiddle")); + + { + NbModuleSuite.Configuration conf = common.reuseUserDir(true).addTest(CachingAndExternalPathsTest.class, "testReadAccess", "testVerifyActivatorExecuted"); + suite.addTest(NbModuleSuite.create(conf)); + } + + return suite; + } + + public void testInitUserDir() throws Exception { + File simpleModule = new File(System.getProperty("external.jar")); + + File newModule = new File(new File(new File(System.getProperty("netbeans.user")), "modules"), "org-external.jar"); + newModule.getParentFile().mkdirs(); + simpleModule.renameTo(newModule); + assertTrue("New module correctly created", newModule.exists()); + + class Activate implements FileSystem.AtomicAction { + FileObject fo; + + public Activate() throws IOException { + } + + public void run() throws IOException { + fo = FileUtil.getConfigFile("Modules").createData("org-external.xml"); + OutputStream os = fo.getOutputStream(); + os.write(( + "\n" + + "\n" + + "\n" + + " false\n" + + " false\n" + + " true\n" + + " modules/org-external.jar\n" + + " false\n" + + "\n" + + "").getBytes()); + os.close(); + } + } + Activate a = new Activate(); + System.getProperties().remove("activated.ok"); + + LOG.log(Level.INFO, "Creating config file"); + FileUtil.runAtomicAction(a); + LOG.log(Level.INFO, "Done creating {0}", a.fo); + + + for (int i = 0; i < 360 && System.getProperty("activated.ok") == null; i++) { + LOG.log(Level.INFO, "Not found, but activated.ok: {0}", System.getProperty("activated.ok")); + Thread.sleep(500); + } + LOG.log(Level.INFO, "activated.ok: {0}", System.getProperty("activated.ok")); + assertEquals("true", System.getProperty("activated.ok")); + doNecessarySetup(); + + LOG.info("testInitUserDir - finished"); + } + + public void testStartAgain() throws Exception { + doNecessarySetup(); + // will be reset next time the system starts + System.getProperties().remove("netbeans.dirs"); + // initializes counting, but waits till netbeans.dirs are provided + // by NbModuleSuite + LOG.info("testStartAgain - enabling initCheckReadAccess"); + initCheckReadAccess(); + LOG.info("testStartAgain - finished"); + } + + static void doNecessarySetup() throws ClassNotFoundException, IOException { + ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class); + try { + Class c = Class.forName("javax.help.HelpSet", true, l); + } catch (ClassNotFoundException ok) { + } + try { + Class d = Class.forName("org.openide.DialogDescriptor", true, l); + } catch (ClassNotFoundException ok) { + } + FileObject fo = FileUtil.getConfigFile("Services/Browsers"); + if (fo != null) { + fo.delete(); + } + } + + public void testInMiddle() { + LOG.info("Previous run finished, starting another one"); + System.setProperty("activated.count", "0"); + } + + public void testReadAccess() throws Exception { + LOG.info("Inside testReadAccess"); + ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class); + try { + Class c = Class.forName("javax.help.HelpSet", true, l); + } catch (ClassNotFoundException ex) { + // never mind + } + try { + if (CountingSecurityManager.isEnabled()) { + CountingSecurityManager.assertCounts("No reads during startup", 0); + } else { + LOG.warning("Initialization mode, counting is disabled"); + } + } catch (Error e) { + e.printStackTrace(getLog("file-reads-report.txt")); + throw e; + } + } + + public void testVerifyActivatorExecuted() { + assertEquals("1", System.getProperty("activated.count")); + } + + public static class Compile extends NbTestCase { + private File simpleModule; + private SetExtDirProperty set; + + public Compile(String name, SetExtDirProperty p) { + super(name); + set = p; + } + + public void testCompile() throws Exception { + File data = new File(getDataDir(), "jars"); + File jars = new File(getWorkDir(), "jars"); + simpleModule = SetupHid.createTestJAR(data, jars, "external", null); + + File ext = new File(getWorkDir(), "extjars"); + ext.mkdirs(); + File extJAR = SetupHid.createTestJAR(data, ext, "ext", "activate"); + + System.setProperty("external.jar", simpleModule.getPath()); + set.setExtDirProperty(ext); + } + } + + protected interface SetExtDirProperty { + public void setExtDirProperty(File value); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/CachingAndExternalURLTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/CachingAndExternalURLTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.IOException; +import junit.framework.Test; + +public class CachingAndExternalURLTest { + public static Test suite() throws IOException { + return CachingAndExternalPathsTest.create(new CachingAndExternalPathsTest.SetExtDirProperty() { + public void setExtDirProperty(File value) { + System.setProperty("ext.dir", value.toURI().toString()); + } + }); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/CachingPreventsFileTouchesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/CachingPreventsFileTouchesTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,226 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import junit.framework.Test; +import org.netbeans.SetupHid; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.netbeans.junit.NbTestSuite; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileSystem; +import org.openide.filesystems.FileUtil; +import org.openide.util.Lookup; + +/** + * Read access test + * see details on http://wiki.netbeans.org/FitnessViaWhiteAndBlackList + */ +public class CachingPreventsFileTouchesTest extends NbTestCase { + private static final Logger LOG = Logger.getLogger(CachingPreventsFileTouchesTest.class.getName()); + static { + System.setProperty("java.awt.headless", "true"); + } + + private static void initCheckReadAccess() throws IOException { + Set allowedFiles = new HashSet(); + CountingSecurityManager.initialize(null, CountingSecurityManager.Mode.CHECK_READ, allowedFiles); + } + + public CachingPreventsFileTouchesTest(String name) { + super(name); + } + + public static Test suite() throws IOException { + Locale.setDefault(Locale.US); + CountingSecurityManager.initialize("none", CountingSecurityManager.Mode.CHECK_READ, null); + System.setProperty("org.netbeans.Stamps.level", "ALL"); + System.setProperty(NbModuleSuite.class.getName() + ".level", "FINE"); + System.setProperty("org.netbeans.modules.netbinox.level", "FINE"); + + NbTestSuite suite = new NbTestSuite(); + Compile compile = new Compile("testCompile"); + suite.addTest(compile); + NbModuleSuite.Configuration common = NbModuleSuite.emptyConfiguration().clusters(".*").enableClasspathModules(false) + .gui(false).honorAutoloadEager(true); + { + NbModuleSuite.Configuration conf = common.reuseUserDir(false).addTest(CachingPreventsFileTouchesTest.class, "testInitUserDir"); + suite.addTest(NbModuleSuite.create(conf)); + } + { + NbModuleSuite.Configuration conf = common.reuseUserDir(true).addTest(CachingPreventsFileTouchesTest.class, "testStartAgain"); + suite.addTest(NbModuleSuite.create(conf)); + } + + suite.addTest(new CachingPreventsFileTouchesTest("testInMiddle")); + + { + NbModuleSuite.Configuration conf = common.reuseUserDir(true).addTest(CachingPreventsFileTouchesTest.class, "testReadAccess", "testVerifyActivatorExecuted"); + suite.addTest(NbModuleSuite.create(conf)); + } + + return suite; + } + + public void testInitUserDir() throws Exception { + File simpleModule = new File(System.getProperty("activate.jar")); + + File newModule = new File(new File(new File(System.getProperty("netbeans.user")), "modules"), "org-activate.jar"); + newModule.getParentFile().mkdirs(); + simpleModule.renameTo(newModule); + assertTrue("New module correctly created", newModule.exists()); + + class Activate implements FileSystem.AtomicAction { + public void run() throws IOException { + FileObject fo = FileUtil.getConfigFile("Modules").createData("org-activate.xml"); + OutputStream os = fo.getOutputStream(); + os.write(( + "\n" + + "\n" + + "\n" + + " false\n" + + " false\n" + + " true\n" + + " modules/org-activate.jar\n" + + " false\n" + + "\n" + + "").getBytes()); + os.close(); + } + } + + FileUtil.runAtomicAction(new Activate()); + + + Class main = null; + Object s = null; + for (int i = 0; i < 360; i++) { + LOG.log(Level.INFO, "testInitUserDir - waiting for activation {0}", i); + try { + main = Thread.currentThread().getContextClassLoader().loadClass("org.activate.Main"); + s = main.getField("start").get(null); + if (s == null) { + Thread.sleep(500); + continue; + } + } catch (ClassNotFoundException ex) { + Thread.sleep(500); + continue; + } + break; + } + LOG.log(Level.INFO, "testInitUserDir - waiting for activation over. Testing."); + assertNotNull("Activate module shall start", main); + LOG.log(Level.INFO, "checking field from {0}", main); + s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + + CachingAndExternalPathsTest.doNecessarySetup(); + + LOG.info("testInitUserDir - finished"); + } + + public void testStartAgain() throws Exception { + CachingAndExternalPathsTest.doNecessarySetup(); + // will be reset next time the system starts + System.getProperties().remove("netbeans.dirs"); + // initializes counting, but waits till netbeans.dirs are provided + // by NbModuleSuite + LOG.info("testStartAgain - enabling initCheckReadAccess"); + initCheckReadAccess(); + LOG.info("testStartAgain - finished"); + } + + public void testInMiddle() { + LOG.info("Previous run finished, starting another one"); + System.setProperty("activated.count", "0"); + } + + public void testReadAccess() throws Exception { + LOG.info("Inside testReadAccess"); + ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class); + try { + Class c = Class.forName("javax.help.HelpSet", true, l); + } catch (ClassNotFoundException ex) { + // never mind + } + try { + if (CountingSecurityManager.isEnabled()) { + CountingSecurityManager.assertCounts("No reads during startup", 0); + } else { + Logger.getLogger("TEST.testReadAccess").warning("Initialization mode, counting is disabled"); + } + } catch (Error e) { + e.printStackTrace(getLog("file-reads-report.txt")); + throw e; + } + } + + public void testVerifyActivatorExecuted() { + assertEquals("1", System.getProperty("activated.count")); + } + + public static class Compile extends NbTestCase { + private File simpleModule; + + public Compile(String name) { + super(name); + } + + public void testCompile() throws Exception { + File data = new File(getDataDir(), "jars"); + File jars = new File(getWorkDir(), "jars"); + simpleModule = SetupHid.createTestJAR(data, jars, "activate", "activate"); + + System.setProperty("activate.jar", simpleModule.getPath()); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/ContextClassLoaderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/ContextClassLoaderTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.awt.GraphicsEnvironment; +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import java.util.logging.Level; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.netbeans.core.startup.Main; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.netbeans.junit.NbTestSuite; + +/** + * + * @author Jaroslav Tulach + */ +public class ContextClassLoaderTest extends NbTestCase { + static { + System.setProperty("java.awt.headless", "true"); + } + + public ContextClassLoaderTest(String name) { + super(name); + } + + public static Test suite() { + System.setProperty("java.awt.headless", "true"); + assertTrue("In headless mode", GraphicsEnvironment.isHeadless()); + NbTestSuite s = new NbTestSuite(); + s.addTest(new Compile("testCompileJAR")); + s.addTest(NbModuleSuite.create( + NbModuleSuite.emptyConfiguration().addTest( + ContextClassLoaderTest.class + ).honorAutoloadEager(true).clusters( + ".*" + ).failOnException(Level.WARNING)/*.failOnMessage(Level.WARNING)*/ + .gui(false) + )); + return s; + } + + public void testCheckWhichContainerIsRunning() throws Exception { + File j1 = new File(System.getProperty("activate.jar")); + assertTrue("File " + j1 + " exists", j1.exists()); + + + ModuleManager mgr = Main.getModuleSystem().getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + Module m1; + + m1 = mgr.create(j1, null, false, false, false); + mgr.enable(m1); + + assertTrue("OSGi module is now enabled", m1.isEnabled()); + mgr.mutexPrivileged().exitWriteAccess(); + + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + + ClassLoader l = (ClassLoader) main.getField("loader").get(null); + assertNotNull("Classloader is provided", l); + Class c = l.loadClass("org.netbeans.modules.favorites.Tab"); + assertNotNull("Class from favorites module found in " + l, c); + + Class main2 = Thread.currentThread().getContextClassLoader().loadClass(main.getName()); + assertSame("Context classloader loads the same class", main, main2); + + Class main3 = l.loadClass(main.getName()); + assertSame("Bundle's context classloader loads the same class", main, main3); + } + + public void testContextClassLoaderIsOK() throws ClassNotFoundException { + ClassLoader l = Thread.currentThread().getContextClassLoader(); + assertNotNull("Context class loader is found", l); + + Class c = l.loadClass("org.netbeans.modules.favorites.Tab"); + assertNotNull("Class from favorites module found in " + l, c); + } + + public static class Compile extends SetupHid { + + public Compile(String name) { + super(name); + } + @Override + protected void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + } + + public void testCompileJAR() throws Exception { + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + + jars.mkdirs(); + File j1 = createTestJAR("activate", null); + assertNotNull("file found: " + j1); + System.setProperty("activate.jar", j1.getPath()); + } + + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/CountingSecurityManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/CountingSecurityManager.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,545 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Field; +import java.security.Permission; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.logging.Logger; +import junit.framework.Assert; + +/** + * + * @author Jaroslav Tulach + */ +final class CountingSecurityManager extends SecurityManager implements Callable { + private static int cnt; + private static StringWriter msgs; + private static PrintWriter pw; + private static String prefix; + private static Map who = new HashMap(); + private static Set allowed = Collections.emptySet(); + private static SecurityManager man; + private static Mode mode; + + public enum Mode { + CHECK_READ, CHECK_WRITE + }; + + public static void initialize(String prefix, Mode mode, Set allowedFiles) { + System.setProperty("counting.security.disabled", "true"); + + if (System.getSecurityManager() instanceof CountingSecurityManager) { + // ok + } else { + System.setSecurityManager(new CountingSecurityManager()); + } + setCnt(0); + msgs = new StringWriter(); + pw = new PrintWriter(msgs); + CountingSecurityManager.prefix = prefix; + CountingSecurityManager.mode = mode; + allowed = allowedFiles; + + Logger.getLogger("org.netbeans.TopSecurityManager").setLevel(Level.OFF); + System.setProperty("org.netbeans.TopSecurityManager.level", "3000"); + System.setProperty("counting.security.disabled", "false"); + } + + static void assertReflection(int maxCount, String whitelist) { + System.setProperty("counting.reflection.whitelist", whitelist); + System.getSecurityManager().checkMemberAccess(null, maxCount); + System.getProperties().remove("counting.reflection.whitelist"); + } + + @Override + public String toString() { + return msgs.toString(); + } + + public Integer call() throws Exception { + return cnt; + } + + public static boolean isEnabled() { + return System.getSecurityManager() instanceof Callable; + } + + public static void assertCounts(String msg, int expectedCnt) throws Exception { + int c = (Integer)((Callable)System.getSecurityManager()).call(); + Assert.assertEquals(msg + "\n" + System.getSecurityManager().toString(), expectedCnt, c); + setCnt(0); + msgs = new StringWriter(); + pw = new PrintWriter(msgs); + } + + /** + * @return the cnt + */ + public static int getCnt() { + return cnt; + } + + /** + * @param aCnt the cnt to set + */ + public static void setCnt(int aCnt) { + cnt = aCnt; + } + + @Override + public void checkPermission(Permission p) { + if (isDisabled()) { + return; + } + if (p instanceof RuntimePermission && "setSecurityManager".equals(p.getName())) { + try { + ClassLoader l = Thread.currentThread().getContextClassLoader(); + Class manClass = Class.forName("org.netbeans.TopSecurityManager", false, l); + man = (SecurityManager) manClass.newInstance(); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + throw new SecurityException(); + } + } + + @Override + public final void checkPropertyAccess(String x) { + if (man != null) { + man.checkPropertyAccess(x); + } + } + + @Override + public void checkRead(String file) { + if (mode == Mode.CHECK_READ && acceptFileRead(file)) { + String dirs = System.getProperty("netbeans.dirs"); + if (dirs == null) { + // not initialized yet + return; + } + + setCnt(getCnt() + 1); + pw.println("checkRead: " + file); + if (who.get(file) == null) { + Exception now = new Exception("checkRead: " + file); + who.put(file, now); + now.printStackTrace(pw); + pw.flush(); + } + } + } + + @Override + public void checkRead(String file, Object context) { + /* + if (file.startsWith(prefix)) { + cnt++; + pw.println("checkRead2: " + file); + } + */ + } + + private void assertMembers(int cnt) { + String res = System.getProperty("counting.reflection.whitelist"); + if (res == null) { + Assert.fail("Please provide whitelist: " + res); + } + Properties okAccess = new Properties(); + try { + okAccess.load(CountingSecurityManager.class.getResourceAsStream(res)); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + + int myCnt = 0; + StringWriter w = new StringWriter(); + PrintWriter p = new PrintWriter(w); + Set m; + synchronized (members) { + m = new TreeSet(members.values()); + } + for (Who wh : m) { + if (wh.isIgnore()) { + continue; + } + String howMuchIsOK = okAccess.getProperty(wh.clazz.getName()); + if (howMuchIsOK != null && Integer.parseInt(howMuchIsOK) >= wh.count) { + continue; + } + + myCnt += wh.count; + wh.printStackTrace(p); + wh.count = 0; + } + if (myCnt > cnt) { + Assert.fail("Expected at much " + cnt + " reflection efforts, but was: " + myCnt + "\n" + w); + } + } + + private final Map members = Collections.synchronizedMap(new HashMap()); + @Override + public void checkMemberAccess(Class clazz, int which) { + if (clazz == null) { + assertMembers(which); + } + + Who w = members.get(clazz); + if (w == null) { + w = new Who(clazz); + members.put(clazz, w); + } + w.count++; + } + + private static class Who extends Exception implements Comparable { + int hashCode; + final Class clazz; + int count; + + public Who(Class who) { + super(""); + this.clazz = who; + } + + @Override + public void printStackTrace(PrintWriter s) { + s.println(clazz.getName() + "=" + count); + super.printStackTrace(s); + } + + @Override + public int hashCode() { + if (hashCode != 0) { + return hashCode; + } + hashCode = clazz.hashCode(); + for (StackTraceElement stackTraceElement : getStackTrace()) { + hashCode = hashCode * 2 + stackTraceElement.hashCode(); + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Who other = (Who) obj; + if (this.clazz != other.clazz) { + return false; + } + if (this.hashCode() != other.hashCode()) { + return false; + } + return Arrays.equals(getStackTrace(), other.getStackTrace()); + } + + public int compareTo(Who o) { + if (o == this) { + return 0; + } + if (o.count < this.count) { + return -1; + } + if (o.count > this.count) { + return 1; + } + return this.clazz.getName().compareTo(o.clazz.getName()); + } + + private boolean isIgnore() { + if (clazz.getName().startsWith("sun.reflect.Generated")) { + return true; + } + if (clazz.getName().startsWith("$Proxy")) { + return true; + } + if (clazz.getName().startsWith("org.apache.tools.ant.")) { + return true; + } + if (clazz.getName().startsWith("sun.nio.")) { + return true; + } + + for (StackTraceElement stackTraceElement : getStackTrace()) { + if (stackTraceElement.getClassName().contains("CountingSecurityManager")) { + continue; + } + if (stackTraceElement.getClassName().equals("java.lang.Class")) { + continue; + } + if (stackTraceElement.getClassName().startsWith("java.lang.Thread")) { + if (stackTraceElement.getMethodName().equals("auditSubclass")) { + return true; + } + continue; + } + if (stackTraceElement.getClassName().startsWith("java.security.AccessController")) { + continue; + } + if (stackTraceElement.getClassName().equals("sun.swing.SwingLazyValue")) { + // ignore createValue method + return true; + } + if ( + stackTraceElement.getClassName().equals("java.awt.Component") && + stackTraceElement.getMethodName().equals("isCoalesceEventsOverriden") + ) { + return true; + } + if (stackTraceElement.getClassName().startsWith("java.util.ResourceBundle")) { + // ignore these invocations + return true; + } + if (stackTraceElement.getClassName().equals("org.netbeans.jellytools")) { + // ignore these invocations + return true; + } + if (stackTraceElement.getClassName().equals("org.openide.util.lookup.MetaInfServicesLookup$P")) { + // ignore these invocations + return true; + } + if (stackTraceElement.getClassName().equals("org.openide.util.WeakListenerImpl$ListenerReference")) { + // ignore: removeXYZListener is done using reflection + return true; + } + return false; + } + return false; + } + } + + @Override + public void checkWrite(FileDescriptor fd) { + //setCnt(getCnt() + 1); + //pw.println("Fd: " + fd); + } + + @Override + public void checkWrite(String file) { + if (mode == Mode.CHECK_WRITE && acceptFileWrite(file)) { + setCnt(getCnt() + 1); + pw.println("checkWrite: " + file); + if (who.get(file) == null) { + Exception now = new Exception("checkWrite: " + file); + who.put(file, now); + now.printStackTrace(pw); + } + } + } + + @Override + public void checkDelete(String file) { + if (mode == Mode.CHECK_WRITE && acceptFileWrite(file)) { + setCnt(getCnt() + 1); + pw.println("checkDelete: " + file); + } + } + + private boolean acceptFileWrite(String file) { + String ud = System.getProperty("netbeans.user"); + if (ud == null) { + // still initializing + return false; + } + if (!file.startsWith(ud)) { + return false; + } + + String f = file.substring(ud.length()).replace(File.separatorChar, '/'); + if (f.contains("config/Modules")) { + return false; + } + if (f.contains("config/Windows2Local")) { + return false; + } + if (f.endsWith(".hg")) { + try { + Class ref = Class.forName("org.netbeans.modules.versioning.util.Utils", true, Thread.currentThread().getContextClassLoader()); + Field unver = ref.getDeclaredField("unversionedFolders"); + unver.setAccessible(true); + unver.set(null, new File[]{new File(ud).getParentFile()}); + return false; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + if (file.startsWith(ud)) { + if (f.startsWith("/")) { + f = f.substring(1); + } + if (allowed.contains(f)) { + return false; + } + } + + return prefix == null || file.startsWith(prefix); + } + + private boolean acceptFileRead(String file) { + if (prefix != null && !file.startsWith(prefix)) { + return false; + } + if (file.contains("/var/cache/netigso/org.eclipse.osgi/.")) { + // Just finite number of files in a cache + return false; + } + if ( + file.equals(System.getProperty("netbeans.user")) || + file.equals(System.getProperty("netbeans.home")) || + file.matches(".*/modules/ext/org\\.eclipse\\.osgi_[0-9\\.]*v[0-9]*\\.jar") || + file.endsWith("modules/org-netbeans-modules-netbinox.jar") || + file.endsWith("var/cache/netigso") || + file.endsWith("var/cache/netigso/org.eclipse.osgi") + ) { + // equinox just needs to touch some files, preferrably leave them + // under our directory + return false; + } + for (Class onStack : getClassContext()) { + if (onStack.getName().startsWith("org.eclipse.osgi.internal.permadmin.SecurityAdmin")) { + // this is caused by our CountingSecurityManager being on + return false; + } + } + for (Class onStack : getClassContext()) { + if (onStack.getName().startsWith("org.eclipse")) { + return true; + } + } + + if (!file.endsWith(".jar") && !file.endsWith("bundlefile")) { + return false; + } + if (file.endsWith("tests.jar")) { + return false; + } + if (file.endsWith("org-netbeans-modules-nbjunit.jar")) { + return false; + } + if (file.startsWith(System.getProperty("java.home").replaceAll("[/\\\\][^/\\\\]*$", ""))) { + return false; + } + if (file.startsWith(System.getProperty("netbeans.home") + File.separator + "lib")) { + return false; + } + if (file.startsWith(System.getProperty("netbeans.home") + File.separator + "core")) { + return false; + } + String dirs = System.getProperty("netbeans.dirs"); + if (dirs != null) { + for (String dir : dirs.split(File.pathSeparator)) { + if (file.startsWith(dir + File.separator + "lib")) { + return false; + } + if (file.startsWith(dir + File.separator + "core")) { + return false; + } + } + } + // mac osx + dirs = System.getProperty("java.ext.dirs"); + if (dirs != null) { + for (String dir : dirs.split(File.pathSeparator)) { + if (file.startsWith(dir)) { + return false; + } + } + } + + for (Class onStack : getClassContext()) { + if (onStack.getName().equals("org.netbeans.Stamps")) { + return false; + } + } + return true; + } + + @Override + public void checkExec(String cmd) { + if (cmd.contains("chmod")) { + return; + } + if (cmd.equals("hg")) { + return; + } + if (cmd.endsWith("/hg")) { + return; + } + if (cmd.endsWith("hg.exe")) { + return; + } + + super.checkExec(cmd); + setCnt(getCnt() + 1); + pw.println("checkExec: " + cmd); + new Exception().printStackTrace(pw); + } + + @Override + public void checkPermission(Permission perm, Object context) { + } + + /** + * @return the disabled + */ + private static boolean isDisabled() { + return Boolean.getBoolean("counting.security.disabled"); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/EnabledAutoloadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/EnabledAutoloadTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.util.logging.Level; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.netbeans.core.startup.Main; +import org.netbeans.junit.Log; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; + +/** + * + * @author Jaroslav Tulach + */ +public class EnabledAutoloadTest extends NbTestCase { + private File j1; + + public EnabledAutoloadTest(String name) { + super(name); + } + + public static Test suite() { + return NbModuleSuite.create( + NbModuleSuite.emptyConfiguration().addTest( + EnabledAutoloadTest.class + ).honorAutoloadEager(true).clusters("platform.*").failOnException(Level.WARNING)/*.failOnMessage(Level.WARNING)*/ + .gui(false) + ); + } + + @Override + protected void setUp() throws Exception { + clearWorkDir(); + + File jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + + j1 = SetupHid.createTestJAR(getDataDir(), jars, "simple-module.jar", null); + } + + public void testDependOnAutoload() throws Exception { + ModuleManager mgr = Main.getModuleSystem().getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + try { + Module m1; + String mf = "Bundle-SymbolicName: org.require.autoload\n" + + "Bundle-Version: 33.0.3\n" + + "Bundle-ManifestVersion: 2\n" + + "Require-Bundle: org.openide.compat\n\n"; + /* + mf = "OpenIDE-Module: org.require.autoload\n" + + "OpenIDE-Module-Module-Dependencies: org.openide.compat\n\n"; + /**/ + File jj1 = NetigsoHid.changeManifest(getWorkDir(), j1, mf); + m1 = mgr.create(jj1, null, false, false, false); + + CharSequence log = Log.enable("org.netbeans.core.modules", Level.WARNING); + mgr.enable(m1); + + assertTrue("OSGi module is now enabled", m1.isEnabled()); + + Class wl = m1.getClassLoader().loadClass("org.openide.util.WeakListener"); + assertNotNull("Weak listener found", wl); + + Module compat = mgr.get("org.openide.compat"); + assertTrue("Compat module is turned on too", compat.isEnabled()); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/ExternalDirectoryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/ExternalDirectoryTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,174 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.util.Enumeration; +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.FileOutputStream; +import java.net.URL; +import java.util.Locale; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Do we correctly call the BundleActivators? + * + * @author Jaroslav Tulach + */ +public class ExternalDirectoryTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + private File simpleModule; + + public ExternalDirectoryTest(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + File activate = new File(data, "activate"); + assertTrue("Directory exists", activate.isDirectory()); + System.setProperty("ext.dir", data.getPath()); + + File entry = new File(new File(new File(new File(data, "activate"), "org"), "test"), "x.txt"); + entry.getParentFile().mkdirs(); + FileOutputStream os = new FileOutputStream(entry); + os.write("Ahoj".getBytes()); + os.close(); + + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + File activateModule = SetupHid.createTestJAR(data, jars, "activate", null); + // we need just the compiled clases, not the JAR + activateModule.delete(); + simpleModule = SetupHid.createTestJAR(data, jars, "externaldir", null); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + Enumeration en; + int checks = 0; + + System.setProperty("activated.checkentries", "/org/test/x.txt"); + try { + m1 = mgr.create(simpleModule, null, false, false, false); + mgr.enable(m1); + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + + BundleContext bc = (BundleContext)s; + StringBuilder sb = new StringBuilder(); + for (Bundle b : bc.getBundles()) { + URL root = b.getEntry("/"); + if (root == null) { + sb.append("No root URL for ").append(b.getSymbolicName()).append("\n"); + } + + en = b.findEntries("/", null, true); + if (en == null) { + sb.append("No entries for ").append(b.getSymbolicName()).append("\n"); + continue; + } + while (en.hasMoreElements()) { + URL u = (URL) en.nextElement(); + final String ef = u.toExternalForm(); + int pref = ef.indexOf("/org/"); + int last = ef.lastIndexOf("/"); + if (pref != -1 && last != -1) { + String entry = ef.substring(pref + 1, last + 1); + assertTrue("/ is at the end", entry.endsWith("/")); + checks++; + final URL found = b.getEntry(entry); + assertNotNull("Entry found " + entry + " in " + b.getSymbolicName(), found); + + URL notFound = b.getEntry("non/existent/entry/"); + assertNull("Entries for non-existing entries are not found", notFound); + } + } + } + if (sb.length() > 0) { + fail(sb.toString()); + } + if (checks == 0) { + fail("There shall be some checks for entries"); + } + String text = System.getProperty("activated.entry"); + assertEquals("Ahoj", text); + + String localURL = System.getProperty("activated.entry.local"); + assertNotNull("bundleentry read OK", localURL); + assertTrue("external file is referred as file:/.... = " + localURL, localURL.startsWith("file:/")); + assertEquals("Ahoj", readLine(localURL)); + + String fileURL = System.getProperty("activated.entry.file"); + assertNotNull("fileURL found", fileURL); + assertTrue("file:/..... = " + fileURL, fileURL.startsWith("file:/")); + assertEquals("Ahoj", readLine(fileURL)); + + mgr.disable(m1); + + Object e = main.getField("stop").get(null); + assertNotNull("Bundle stopped, its context provided", e); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + + static String readLine(String url) throws Exception { + return BundleURLConnectionTest.readLine(url); + } + +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/ExternalJARTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/ExternalJARTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,132 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.util.Enumeration; +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.FileOutputStream; +import java.net.URL; +import java.util.Locale; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Do we correctly call the BundleActivators? + * + * @author Jaroslav Tulach + */ +public class ExternalJARTest extends SetupHid { + private static ModuleManager mgr; + private File simpleModule; + private File dependsOnSimple; + + public ExternalJARTest(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + File activate = new File(data, "activate"); + assertTrue("Directory exists", activate.isDirectory()); + + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + File activateLib = SetupHid.createTestJAR(data, jars, "activate", null); + System.setProperty("ext.jar", activateLib.getPath()); + + String bundleMan = "Bundle-SymbolicName: org.foo\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Bundle-ClassPath: external:$ext.jar$\n" + + "Import-Package: org.osgi.framework\n" + + "Export-Package: org.activate\n\n\n"; + simpleModule = NetigsoHid.changeManifest( + getWorkDir(), + SetupHid.createTestJAR(data, jars, "simple-module", null), + bundleMan + ); + String depMan = "Manifest-Version: 1.0\n" + + "OpenIDE-Module: org.bar2/1\n" + + "OpenIDE-Module-Module-Dependencies: org.foo\n\n\n"; + dependsOnSimple = NetigsoHid.changeManifest( + getWorkDir(), + SetupHid.createTestJAR(data, jars, "depends-on-simple-module", null, simpleModule), + depMan + ); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + + try { + Module m1 = mgr.create(simpleModule, null, false, true, false); + Module m2 = mgr.create(dependsOnSimple, null, false, false, false); + mgr.enable(m2); + + { + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + assertNotNull("m1 can load class from external library of m1", main); + } + + { + Class main = m2.getClassLoader().loadClass("org.activate.Main"); + assertNotNull("m2 can load class from external library of m1", main); + } + + mgr.disable(m2); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/HookConfiguratorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/HookConfiguratorTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.awt.GraphicsEnvironment; +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import java.util.logging.Level; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.netbeans.core.startup.Main; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.netbeans.junit.NbTestSuite; + +/** + * + * @author Jaroslav Tulach + */ +public class HookConfiguratorTest extends NbTestCase { + static { + System.setProperty("java.awt.headless", "true"); + } + + public HookConfiguratorTest(String name) { + super(name); + } + + public static Test suite() { + System.setProperty("java.awt.headless", "true"); + assertTrue("In headless mode", GraphicsEnvironment.isHeadless()); + NbTestSuite s = new NbTestSuite(); + s.addTest(new Compile("testCompileJAR")); + s.addTest(NbModuleSuite.create( + NbModuleSuite.emptyConfiguration().addTest( + HookConfiguratorTest.class + ).honorAutoloadEager(true).clusters( + ".*" + ).failOnException(Level.WARNING)/*.failOnMessage(Level.WARNING)*/ + .gui(false) + )); + return s; + } + + public void testCheckWhichContainerIsRunning() throws Exception { + File j1 = new File(System.getProperty("activate.jar")); + assertTrue("File " + j1 + " exists", j1.exists()); + File j2 = new File(System.getProperty("hook.jar")); + assertTrue("File " + j2 + " exists", j2.exists()); + + + ModuleManager mgr = Main.getModuleSystem().getManager(); + try { + mgr.mutexPrivileged().enterWriteAccess(); + Module m1, m2; + + m1 = mgr.create(j1, null, false, false, false); + m2 = mgr.create(j2, null, false, false, false); + mgr.enable(m2); + mgr.enable(m1); + + assertTrue("OSGi module is now enabled", m1.isEnabled()); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + + assertEquals("true", System.getProperty("main.hook")); + + } + + public static class Compile extends SetupHid { + + public Compile(String name) { + super(name); + } + @Override + protected void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + } + + public void testCompileJAR() throws Exception { + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + + jars.mkdirs(); + File j1 = createTestJAR("activate", null); + assertNotNull("file found: " + j1); + File j2 = createTestJAR("hook", null); + assertNotNull("file found: " + j2); + System.setProperty("activate.jar", j1.getPath()); + System.setProperty("hook.jar", j2.getPath()); + } + + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/IntegrationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/IntegrationTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.logging.Level; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.NetigsoFramework; +import org.netbeans.SetupHid; +import org.netbeans.core.startup.Main; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.openide.util.Lookup; +import org.osgi.framework.Bundle; +import org.osgi.framework.launch.Framework; + +/** + * + * @author Jaroslav Tulach + */ +public class IntegrationTest extends NbTestCase { + private File j1; + + public IntegrationTest(String name) { + super(name); + } + + public static Test suite() { + return NbModuleSuite.create( + NbModuleSuite.emptyConfiguration().addTest( + IntegrationTest.class + ).honorAutoloadEager(true).clusters( + ".*" + ).failOnException(Level.WARNING)/*.failOnMessage(Level.WARNING)*/ + .gui(false) + ); + } + + @Override + protected void setUp() throws Exception { + File jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + + j1 = SetupHid.createTestJAR(getDataDir(), jars, "simple-module.jar", null); + } + + + public void testCheckWhichContainerIsRunning() throws Exception { + ModuleManager mgr = Main.getModuleSystem().getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + Module m1; + String mf = "Bundle-SymbolicName: org.foo\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Export-Package: org.foo"; + + File jj1 = NetigsoHid.changeManifest(getWorkDir(), j1, mf); + m1 = mgr.create(jj1, null, false, false, false); + mgr.enable(m1); + + assertTrue("OSGi module is now enabled", m1.isEnabled()); + mgr.mutexPrivileged().exitWriteAccess(); + + Object obj = Lookup.getDefault().lookup(NetigsoFramework.class); + final Method m = obj.getClass().getDeclaredMethod("getFramework"); + m.setAccessible(true); + Framework w = (Framework) m.invoke(obj); + assertNotNull("Framework found", w); + assertEquals("Felix is not in its name", -1, w.getClass().getName().indexOf("felix")); + StringBuilder sb = new StringBuilder(); + for (Bundle b : w.getBundleContext().getBundles()) { + sb.append("\n").append(b.getSymbolicName()); + if (b.getSymbolicName().equals("org.eclipse.osgi")) { + return; + } + } + fail("Expecting equinox among list of enabled bundles:" + sb); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetbinoxBuddyClassLoaderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetbinoxBuddyClassLoaderTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Locale; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Does context classloader in NetBeans honour the Equinox buddy policy? + * + * @author Jaroslav Tulach + */ +public class NetbinoxBuddyClassLoaderTest extends SetupHid { + private static Module m1; + private Module m2; + private static ModuleManager mgr; + private int cnt; + private File simpleBundle; + private File activate; + + public NetbinoxBuddyClassLoaderTest(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + + File act = createTestJAR("activate", null); + String amf = "Manifest-Version: 1.0\n" + + "Bundle-SymbolicName: org.activate\n" + + "Bundle-Version: 1.2\n" + + "Eclipse-BuddyPolicy: registered\n" + + "Import-Package: org.osgi.framework\n" + + "Bundle-Activator: org.activate.Main\n" + + "\n"; + activate = NetigsoHid.changeManifest(getWorkDir(), act, amf); + + File simpleModule = createTestJAR("simple-module", null); + String mf = "Bundle-SymbolicName: org.snd.module\n" + + "Export-Package: org.foo\n" + + "Require-Bundle: org.activate\n" + + "Eclipse-RegisterBuddy: org.activate\n" + + "Bundle-Version: 33.0.3\n" + + "Bundle-ManifestVersion: 2\n"; + simpleBundle = NetigsoHid.changeManifest(getWorkDir(), simpleModule, mf); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + BundleContext bc; + Method loadClass = null; + try { + m1 = mgr.create(activate, null, false, false, false); + m2 = mgr.create(simpleBundle, null, false, false, false); + + mgr.enable(m1); + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + bc = (BundleContext) s; + loadClass = main.getMethod("loadClass", String.class, ClassLoader.class); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + Bundle toEnable = null; + for (Bundle b : bc.getBundles()) { + if (b.getSymbolicName().equals("org.snd.module")) { + toEnable = b; + break; + } + } + + assertNotNull("org.snd.module bundle found", toEnable); + assertEquals("Just resolved", Bundle.RESOLVED, toEnable.getState()); + assertFalse("not started", m2.isEnabled()); + + Class directly = (Class) loadClass.invoke(null, "org.foo.Something", null); + assertNotNull("Bundle knows how to load the class from its buddy", directly); + + Class someFromBundle = (Class) loadClass.invoke(null, "org.foo.Something", m1.getClassLoader()); + assertNotNull("Bundle knows how to load the class from its buddy", someFromBundle); + + Class some = (Class) loadClass.invoke(null, "org.foo.Something", Thread.currentThread().getContextClassLoader()); + assertNotNull("Context class loader deals with buddies too", some); + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetbinoxLibraryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetbinoxLibraryTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,121 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.util.Enumeration; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Locale; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.framework.adaptor.BundleData; +import org.eclipse.osgi.framework.internal.core.AbstractBundle; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Is loading of libraries OK? + * + * @author Jaroslav Tulach + */ +public class NetbinoxLibraryTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + + public NetbinoxLibraryTest(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + File simpleModule = createTestJAR("activate", null); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + Enumeration en; + int checks = 0; + try { + System.setProperty("activated.library", "does.not.exist"); + + File simpleModule = new File(jars, "activate.jar"); + m1 = mgr.create(simpleModule, null, false, false, false); + mgr.enable(m1); + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + + String err = System.getProperty("activated.library"); + // the error is taken from ClassLoader.loadLibrary + if (err == null || err.indexOf("in java.library.path") == -1) { + fail("The make sure the ClassLoader.findLibrary returns null: " + err); + } + + mgr.disable(m1); + + Object e = main.getField("stop").get(null); + assertNotNull("Bundle stopped, its context provided", e); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetbinoxUseSystemPropertiesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetbinoxUseSystemPropertiesTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009-2010 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.BundleContext; + +/** + * Are system properties properly initialized when specifying + * osgi.framework.useSystemProperties? + * + * @author Jaroslav Tulach + */ +public class NetbinoxUseSystemPropertiesTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + static { + System.setProperty("osgi.framework.useSystemProperties", "true"); + } + + public NetbinoxUseSystemPropertiesTest(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + File simpleModule = createTestJAR("activate", null); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + try { + File simpleModule = new File(jars, "activate.jar"); + m1 = mgr.create(simpleModule, null, false, false, false); + mgr.enable(m1); + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + + BundleContext bc = (BundleContext)s; + assertNotNull("OSGi version available to contexts", bc.getProperty("osgi.framework.version")); + String version = System.getProperty("osgi.framework.version"); + assertNotNull("OSGi version available to System.properties", version); + + mgr.disable(m1); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoActivationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoActivationTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,172 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.util.Enumeration; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Locale; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.framework.adaptor.BundleData; +import org.eclipse.osgi.framework.internal.core.AbstractBundle; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Do we correctly call the BundleActivators? + * + * @author Jaroslav Tulach + */ +public class NetigsoActivationTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + + public NetigsoActivationTest(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + File simpleModule = createTestJAR("activate", null); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + Enumeration en; + int checks = 0; + try { + File simpleModule = new File(jars, "activate.jar"); + m1 = mgr.create(simpleModule, null, false, false, false); + mgr.enable(m1); + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + + BundleContext bc = (BundleContext)s; + StringBuilder sb = new StringBuilder(); + for (Bundle b : bc.getBundles()) { + URL root = b.getEntry("/"); + if (root == null) { + sb.append("No root URL for ").append(b.getSymbolicName()).append("\n"); + } + BundleFile bFile = null; + if (b instanceof AbstractBundle) { + BundleData bd = ((AbstractBundle) b).getBundleData(); + if (bd instanceof BaseData) { + bFile = ((BaseData) bd).getBundleFile(); + } + } + assertNotNull("All our bundles have BundleFile", bFile); + + en = b.findEntries("/", null, true); + if (en == null) { + sb.append("No entries for ").append(b.getSymbolicName()).append("\n"); + continue; + } + while (en.hasMoreElements()) { + URL u = (URL) en.nextElement(); + final String ef = u.toExternalForm(); + int pref = ef.indexOf("/org/"); + int last = ef.lastIndexOf("/"); + if (pref != -1 && last != -1) { + String entry = ef.substring(pref + 1, last + 1); + assertTrue("/ is at the end", entry.endsWith("/")); + checks++; + final URL found = b.getEntry(entry); + assertNotNull("Entry found " + entry + " in " + b.getSymbolicName(), found); + assertTrue("Directory found", bFile.containsDir(entry)); + BundleEntry ee = bFile.getEntry(entry); + URL local = ee.getLocalURL(); + assertEquals("JAR protocol used", "jar", local.getProtocol()); + if (!local.toExternalForm().contains("!/")) { + fail("!/ shall be in the URL: " + local); + } + + final String nonExist = "non/existent/entry/"; + URL notFound = b.getEntry(nonExist); + assertNull("Entries for non-existing entries are not found", notFound); + assertFalse("Non-existent not found", bFile.containsDir(nonExist)); + } + } + } + if (sb.length() > 0) { + fail(sb.toString()); + } + if (checks == 0) { + fail("There shall be some checks for entries"); + } + + assertNotNull("OSGi version available to contexts", bc.getProperty("osgi.framework.version")); + + String version = System.getProperty("osgi.framework.version"); + assertNull("Version is not available in system properties by default", version); + + mgr.disable(m1); + + Object e = main.getField("stop").get(null); + assertNotNull("Bundle stopped, its context provided", e); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoActivationWithAllDirsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoActivationWithAllDirsTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,57 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +/** + * Do we correctly call the BundleActivators? + * + * @author Jaroslav Tulach + */ +public class NetigsoActivationWithAllDirsTest extends NetigsoActivationTest { + static { + generateAllDirs = true; + } + + public NetigsoActivationWithAllDirsTest(String name) { + super(name); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoDashnamesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoDashnamesTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import org.netbeans.MockModuleInstaller; +import org.netbeans.MockEvents; +import org.netbeans.Module; +import org.netbeans.ModuleManager; + +/** + * Tests that dashnames are properly converted to underscores. + * + * @author Jaroslav Tulach + */ +public class NetigsoDashnamesTest extends NetigsoHid { + public NetigsoDashnamesTest(String name) { + super(name); + } + + public void testDashnames() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + Module m2; + Module m1; + HashSet both = null; + try { + String mf = "Bundle-SymbolicName: org.foo-bar\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Export-Package: org.foo"; + String mfBar = + "OpenIDE-Module: org.bar/1\n" + + "OpenIDE-Module-Name: Depends on bar test module\n" + + "OpenIDE-Module-Module-Dependencies: org.foo_bar\n" + + "some"; + + File j1 = changeManifest(new File(jars, "simple-module.jar"), mf); + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + m1 = mgr.create(j1, null, false, false, false); + m2 = mgr.create(j2, null, false, false, false); + HashSet b = new HashSet(Arrays.asList(m1, m2)); + mgr.enable(b); + both = b; + + + Class clazz = m2.getClassLoader().loadClass("org.bar.SomethingElse"); + Class sprclass = m2.getClassLoader().loadClass("org.foo.Something"); + + assertEquals("Correct parent is used", sprclass, clazz.getSuperclass()); + + } finally { + if (both != null) { + mgr.disable(both); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoHid.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoHid.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import org.netbeans.Events; +import org.netbeans.JarClassLoader; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.openide.filesystems.FileUtil; + +/** + * Basic infrastructure for testing OSGi functionality. + * + * @author Jaroslav Tulach + */ +public class NetigsoHid extends SetupHid { + public NetigsoHid(String name) { + super(name); + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + File simpleModule = createTestJAR("simple-module", null); + File dependsOnSimpleModule = createTestJAR("depends-on-simple-module", null, simpleModule); + + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + + System.setProperty("netbeans.user", ud.getPath()); + } + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } + + + protected final File changeManifest(File orig, String manifest) throws IOException { + return changeManifest(getWorkDir(), orig, manifest); + } + + protected static File changeManifest(File dir, File orig, String manifest) throws IOException { + File f = new File(dir, orig.getName()); + Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8"))); + mf.getMainAttributes().putValue("Manifest-Version", "1.0"); + JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf); + JarFile jf = new JarFile(orig); + Enumeration en = jf.entries(); + InputStream is; + while (en.hasMoreElements()) { + JarEntry e = en.nextElement(); + if (e.getName().equals("META-INF/MANIFEST.MF")) { + continue; + } + os.putNextEntry(e); + is = jf.getInputStream(e); + FileUtil.copy(is, os); + is.close(); + os.closeEntry(); + } + os.close(); + + return f; + } + private static final class DummyModule extends Module { + private final Manifest manifest; + public DummyModule(ModuleManager mgr, Events ev, Object history, boolean reloadable, boolean autoload, boolean eager) throws IOException { + super(mgr, ev, history, reloadable, autoload, eager); + manifest = new Manifest(); + manifest.getMainAttributes().putValue("OpenIDE-Module", "boom"); + parseManifest(); + } + @Override + public List getAllJars() { + return Collections.emptyList(); + } + @Override + public void setReloadable(boolean r) { + } + @Override + public void reload() throws IOException { + } + @Override + protected void classLoaderUp(Set parents) throws IOException { + classloader = new JarClassLoader(Collections.emptyList(), new ClassLoader[] {new NoOpClassLoader()}); + } + @Override + protected void classLoaderDown() { + } + @Override + protected void cleanup() { + } + @Override + protected void destroy() { + } + @Override + public boolean isFixed() { + return true; + } + @Override + public Object getLocalizedAttribute(String attr) { + return null; + } + public @Override Manifest getManifest() { + return manifest; + } + } + + private static final class NoOpClassLoader extends ClassLoader { + NoOpClassLoader() { + super(ClassLoader.getSystemClassLoader()); + } + protected @Override Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + if ("java.lang.String".equals(name)) { + throw new ClassNotFoundException("NoOpClassLoader cannot load " + name); + } + return super.loadClass(name, resolve); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoLayerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoLayerTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import org.netbeans.core.startup.*; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Locale; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.netbeans.junit.NbTestSuite; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * How does OSGi integration deals with layer registration? + * + * @author Jaroslav Tulach + */ +public class NetigsoLayerTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + + public NetigsoLayerTest(String name) { + super(name); + } + + public static Test suite() { + Test t = null; +// t = new NetigsoTest("testOSGiCanRequireBundleOnNetBeans"); + if (t == null) { + t = new NbTestSuite(NetigsoLayerTest.class); + } + return t; + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); +// NetigsoModuleFactory.clear(); + + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + File simpleModule = createTestJAR("simple-module", null); + File dependsOnSimpleModule = createTestJAR("depends-on-simple-module", null, simpleModule); + + if (System.getProperty("netbeans.user") == null) { + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + + System.setProperty("netbeans.user", ud.getPath()); + + + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + try { + File j1 = new File(jars, "simple-module.jar"); + m1 = mgr.create(j1, null, false, false, false); + mgr.enable(Collections.singleton(m1)); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } + public void testOSGiCanProvideLayer() throws Exception { + mgr.mutexPrivileged().enterWriteAccess(); + FileObject fo; + try { + String mfBar = "Bundle-SymbolicName: org.bar\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Import-Package: org.foo\n" + + "OpenIDE-Module-Layer: org/bar/layer.xml\n" + + "\n\n"; + + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + Module m2 = mgr.create(j2, null, false, false, false); + mgr.enable(m2); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + fo = FileUtil.getConfigFile("TestFolder"); + assertNotNull("Folder found", fo); + + URL u = mgr.getClassLoader().getResource("org/bar/layer.xml"); + assertNotNull("System ClassLoader can load resources", u); + } +/* Looks like non-exported packages do not work, as the URLHandlersBundleStreamHandler gets + * somehow confused. + * + public void testOSGiCanProvideImpl() throws Exception { + mgr.mutexPrivileged().enterWriteAccess(); + FileObject fo; + try { + String mfBar = "Bundle-SymbolicName: org.kuk\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Import-Package: org.foo\n" + + "OpenIDE-Module-Layer: org/bar/impl/layer.xml\n" + + "\n\n"; + + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + Module m2 = mgr.create(j2, null, false, false, false); + mgr.enable(m2); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + fo = Repository.getDefault().getDefaultFileSystem().findResource("TestImplFolder"); + assertNotNull("Folder found", fo); + } +*/ + private File changeManifest(File orig, String manifest) throws IOException { + File f = new File(getWorkDir(), orig.getName()); + Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8"))); + mf.getMainAttributes().putValue("Manifest-Version", "1.0"); + JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf); + JarFile jf = new JarFile(orig); + Enumeration en = jf.entries(); + InputStream is; + while (en.hasMoreElements()) { + JarEntry e = en.nextElement(); + if (e.getName().equals("META-INF/MANIFEST.MF")) { + continue; + } + os.putNextEntry(e); + is = jf.getInputStream(e); + FileUtil.copy(is, os); + is.close(); + os.closeEntry(); + } + os.close(); + + return f; + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoLoggingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoLoggingTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,115 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Locale; +import java.util.logging.Level; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.netbeans.junit.Log; +import org.netbeans.junit.NbTestSuite; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Do we correctly call the BundleActivators? + * + * @author Jaroslav Tulach + */ +public class NetigsoLoggingTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + private int cnt; + + public NetigsoLoggingTest(String name) { + super(name); + } + + public static Test suite() { + Test t = null; +// t = new NetigsoTest("testOSGiCanRequireBundleOnNetBeans"); + if (t == null) { + t = new NbTestSuite(NetigsoLoggingTest.class); + } + return t; + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + File simpleModule = createTestJAR("activate", null); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + try { + File simpleModule = new File(jars, "activate.jar"); + m1 = mgr.create(simpleModule, null, false, false, false); + System.setProperty("activated.throw", "error!"); + CharSequence log = Log.enable("", Level.WARNING); + mgr.enable(m1); + if (!log.toString().contains("error!")) { + fail("There shall be a warning in the log:\n" + log); + } + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoOSGiActivationVisibleTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoOSGiActivationVisibleTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,150 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.modules.netbinox; + +import java.lang.reflect.Method; +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Are modules turned on by OSGi framework directly marked as enabled? + * Can we load classes from them? + * + * @author Jaroslav Tulach + */ +public class NetigsoOSGiActivationVisibleTest extends SetupHid { + private static Module m1; + private Module m2; + private static ModuleManager mgr; + private int cnt; + private File simpleBundle; + private File activate; + + public NetigsoOSGiActivationVisibleTest(String name) { + super(name); + } + + protected boolean autoload() { + return false; + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + System.setProperty("netbeans.user", ud.getPath()); + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "space in path"); + jars.mkdirs(); + activate = createTestJAR("activate", null); + File simpleModule = createTestJAR("simple-module", null); + + String mf = "Bundle-SymbolicName: org.snd.module\n" + + "Bundle-Version: 33.0.3\n" + + "Bundle-ManifestVersion: 2\n"; + simpleBundle = NetigsoHid.changeManifest(getWorkDir(), simpleModule, mf); + } + + public void testActivation() throws Exception { + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + BundleContext bc; + try { + m1 = mgr.create(activate, null, false, false, false); + m2 = mgr.create(simpleBundle, null, false, autoload(), false); + + mgr.enable(m1); + + Class main = m1.getClassLoader().loadClass("org.activate.Main"); + Object s = main.getField("start").get(null); + assertNotNull("Bundle started, its context provided", s); + bc = (BundleContext) s; + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + Bundle toEnable = null; + for (Bundle b : bc.getBundles()) { + if (b.getSymbolicName().equals("org.snd.module")) { + toEnable = b; + break; + } + } + assertNotNull("org.snd.module bundle found", toEnable); + + assertFalse("not started yet", m2.isEnabled()); + toEnable.start(); + + Class directBundle = toEnable.loadClass("org.foo.Something"); + assertNotNull("Bundle knows how to load the class", directBundle); + + Class someModule = m2.getClassLoader().loadClass("org.foo.Something"); + assertNotNull("Something loaded from module CL", someModule); + + Method loadClass = directBundle.getMethod("loadClass", String.class, ClassLoader.class); + Class directly = (Class) loadClass.invoke(null, "org.foo.Something", null); + assertNotNull("Bundle knows how to load the class from itself without problems", directly); + + Class someFromBundle = (Class) loadClass.invoke(null, "org.foo.Something", someModule.getClassLoader()); + assertNotNull("Bundle knows how to load the class from its using own classloader", someFromBundle); + + Class some = (Class) loadClass.invoke(null, "org.foo.Something", Thread.currentThread().getContextClassLoader()); + assertNotNull("Context class loader loads from disabled module bundles too", some); + + assertFalse("still disabled from NetBeans view point", m2.isEnabled()); + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoOSGiCanDependTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoOSGiCanDependTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import org.netbeans.MockEvents; +import org.netbeans.MockModuleInstaller; +import org.netbeans.Module; +import org.netbeans.ModuleManager; + +/** + * + * @author Jaroslav Tulach + */ +public class NetigsoOSGiCanDependTest extends NetigsoHid { + + public NetigsoOSGiCanDependTest(String name) { + super(name); + } + + public void testOSGiCanDependOnNetBeans() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + HashSet both = null; + try { + String mfBar = "Bundle-SymbolicName: org.bar\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Export-Package: org.bar\n" + + "Import-Package: org.foo\n" + + "\n\n"; + + File j1 = new File(jars, "simple-module.jar"); + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + Module m1 = mgr.create(j1, null, false, false, false); + Module m2 = mgr.create(j2, null, false, false, false); + HashSet b = new HashSet(Arrays.asList(m1, m2)); + mgr.enable(b); + both = b; + + Class clazz = m2.getClassLoader().loadClass("org.bar.SomethingElse"); + Class sprclass = m2.getClassLoader().loadClass("org.foo.Something"); + + assertEquals("Correct parent is used", sprclass, clazz.getSuperclass()); + } finally { + if (both != null) { + mgr.disable(both); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + } + +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoOSGiCanRequestTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoOSGiCanRequestTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import org.netbeans.MockEvents; +import org.netbeans.MockModuleInstaller; +import org.netbeans.Module; +import org.netbeans.ModuleManager; + +/** + * + * @author Jaroslav Tulach + */ +public class NetigsoOSGiCanRequestTest extends NetigsoHid { + + public NetigsoOSGiCanRequestTest(String name) { + super(name); + } + + public void testOSGiCanRequireBundleOnNetBeans() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + HashSet both = null; + try { + String mfBar = "Bundle-SymbolicName: org.bar\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Export-Package: org.bar\n" + + "Require-Bundle: org.foo;bundle-version=\"[100.0,102.0)\"\n" + + "\n\n"; + + File j1 = new File(jars, "simple-module.jar"); + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + Module m1 = mgr.create(j1, null, false, false, false); + Module m2 = mgr.create(j2, null, false, false, false); + HashSet b = new HashSet(Arrays.asList(m1, m2)); + mgr.enable(b); + both = b; + + Class sprclass = m1.getClassLoader().loadClass("org.foo.Something"); + Class clazz = m2.getClassLoader().loadClass("org.bar.SomethingElse"); + + assertEquals("Correct parent is used", sprclass, clazz.getSuperclass()); + } finally { + if (both != null) { + mgr.disable(both); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + } + +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import junit.framework.Test; +import org.netbeans.MockModuleInstaller; +import org.netbeans.MockEvents; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.junit.NbTestSuite; + +/** + * Basic tests to verify the basic interaction between NetBeans module + * system and OSGi. + * + * @author Jaroslav Tulach + */ +public class NetigsoTest extends NetigsoHid { + public NetigsoTest(String name) { + super(name); + } + + public static Test suite() { + Test t = null; +// t = new NetigsoTest("testOSGiCanRequireBundleOnNetBeans"); + if (t == null) { + t = new NbTestSuite(NetigsoTest.class); + } + return t; + } + + public void testFactoryCreatesOurModules() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + Module m2; + Module m1; + HashSet both = null; + try { + String mf = "Bundle-SymbolicName: org.foo\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Export-Package: org.foo"; + String mfBar = + "OpenIDE-Module: org.bar/1\n" + + "OpenIDE-Module-Name: Depends on bar test module\n" + + "OpenIDE-Module-Module-Dependencies: org.foo\n" + + "some"; + + File j1 = changeManifest(new File(jars, "simple-module.jar"), mf); + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + m1 = mgr.create(j1, null, false, false, false); + m2 = mgr.create(j2, null, false, false, false); + HashSet b = new HashSet(Arrays.asList(m1, m2)); + mgr.enable(b); + both = b; + + + Class clazz = m2.getClassLoader().loadClass("org.bar.SomethingElse"); + Class sprclass = m2.getClassLoader().loadClass("org.foo.Something"); + + assertEquals("Correct parent is used", sprclass, clazz.getSuperclass()); + + } finally { + if (both != null) { + mgr.disable(both); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + + } + + public void testFactoryCreatesOurModulesWithDeps() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + HashSet both = null; + try { + String mf = "Bundle-SymbolicName: org.foo\n" + + "Bundle-Version: 1.1.0\n" + + "Bundle-ManifestVersion: 2\n" + + "Export-Package: org.foo"; + String mfBar = + "OpenIDE-Module: org.bar/1\n" + + "OpenIDE-Module-Name: Depends on bar test module\n" + + "OpenIDE-Module-Module-Dependencies: org.foo > 1.0\n" + + "some"; + + File j1 = changeManifest(new File(jars, "simple-module.jar"), mf); + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + Module m1 = mgr.create(j1, null, false, false, false); + Module m2 = mgr.create(j2, null, false, false, false); + HashSet b = new HashSet(Arrays.asList(m1, m2)); + mgr.enable(b); + both = b; + + Class clazz = m2.getClassLoader().loadClass("org.bar.SomethingElse"); + Class sprclass = m2.getClassLoader().loadClass("org.foo.Something"); + + assertEquals("Correct parent is used", sprclass, clazz.getSuperclass()); + } finally { + if (both != null) { + mgr.disable(both); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + } + + + public void testLongDepsAreShortened() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + Module m2 = null; + try { + String mfBar = + "OpenIDE-Module: org.bar/1\n" + + "OpenIDE-Module-Specification-Version: 2.3.0.42.2\n" + + "OpenIDE-Module-Name: Too many dots in version\n" + + "OpenIDE-Module-Public-Packages: org.bar.*\n" + + "some"; + + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + m2 = mgr.create(j2, null, false, false, false); + mgr.enable(m2); + } finally { + if (m2 != null) { + mgr.disable(m2); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + } + + public void testNonNumericVersionNumberIsOK() throws Exception { + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + Module m2 = null; + try { + String mfBar = + "Bundle-SymbolicName: org.bar\n" + + "Bundle-Version: 2.3.0.Prelude-rel24\n" + + "Export-Packages: org.bar.*\n" + + "some"; + + File j2 = changeManifest(new File(jars, "depends-on-simple-module.jar"), mfBar); + m2 = mgr.create(j2, null, false, false, false); + mgr.enable(m2); + assertEquals("2.3.0", m2.getSpecificationVersion().toString()); + assertEquals("2.3.0.Prelude-rel24", m2.getImplementationVersion()); + } finally { + if (m2 != null) { + mgr.disable(m2); + } + mgr.mutexPrivileged().exitWriteAccess(); + } + } +} diff -r 5cee832cf3ae netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoUsesSwingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netbinox/test/unit/src/org/netbeans/modules/netbinox/NetigsoUsesSwingTest.java Tue May 03 21:25:20 2011 +0200 @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Jaroslav Tulach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.netbeans.modules.netbinox; + +import org.netbeans.core.startup.*; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Locale; +import junit.framework.Test; +import org.netbeans.Module; +import org.netbeans.ModuleManager; +import org.netbeans.SetupHid; +import org.netbeans.junit.NbTestSuite; + +/** + * How does OSGi integration deals with dependency on swing? + * + * @author Jaroslav Tulach + */ +public class NetigsoUsesSwingTest extends SetupHid { + private static Module m1; + private static ModuleManager mgr; + private File simpleModule; + + public NetigsoUsesSwingTest(String name) { + super(name); + } + + public static Test suite() { + Test t = null; +// t = new NetigsoTest("testOSGiCanRequireBundleOnNetBeans"); + if (t == null) { + t = new NbTestSuite(NetigsoUsesSwingTest.class); + } + return t; + } + + protected @Override void setUp() throws Exception { + Locale.setDefault(Locale.US); + clearWorkDir(); +// NetigsoModuleFactory.clear(); + + + data = new File(getDataDir(), "jars"); + jars = new File(getWorkDir(), "jars"); + jars.mkdirs(); + simpleModule = createTestJAR("uses-swing", null); + } + + public void testCanReferenceJFrame() throws Exception { + if (System.getProperty("netbeans.user") == null) { + File ud = new File(getWorkDir(), "ud"); + ud.mkdirs(); + + System.setProperty("netbeans.user", ud.getPath()); + + + ModuleSystem ms = Main.getModuleSystem(); + mgr = ms.getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + try { + m1 = mgr.create(simpleModule, null, false, false, false); + mgr.enable(Collections.singleton(m1)); + Class c = m1.getClassLoader().loadClass("org.barwing.Main"); + Runnable r = (Runnable)c.newInstance(); + r.run(); + } finally { + mgr.mutexPrivileged().exitWriteAccess(); + } + } + + } + private File createTestJAR(String name, String srcdir, File... classpath) throws IOException { + return createTestJAR(data, jars, name, srcdir, classpath); + } +}