2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.reglib;
44
import com.sun.servicetag.RegistrationData;
45
import com.sun.servicetag.ServiceTag;
46
import com.sun.servicetag.Registry;
47
import java.io.BufferedInputStream;
48
import java.io.BufferedOutputStream;
49
import java.io.BufferedReader;
50
import java.io.BufferedWriter;
52
import java.io.FileInputStream;
53
import java.io.FileOutputStream;
54
import java.io.FileReader;
55
import java.io.FileWriter;
56
import java.io.IOException;
57
import java.io.InputStream;
58
import java.io.InputStreamReader;
59
import java.io.PrintWriter;
60
import java.util.Collection;
61
import java.util.Locale;
62
import java.util.logging.Level;
63
import java.util.logging.Logger;
70
public class NbServiceTagSupport {
72
private static String NB_CLUSTER;
74
private static String NB_VERSION;
76
private static String GF_VERSION;
78
private static final String USER_HOME = System.getProperty("user.home");
80
private static final String USER_DIR = System.getProperty("netbeans.user");
82
private static final String ST_DIR = "servicetag";
84
private static final String ST_FILE = "servicetag";
86
private static final String REG_FILE = "registration.xml";
88
/** Dir in home dir */
89
private static File svcTagDirHome;
91
/** Dir in install dir */
92
private static File svcTagDirNb;
94
private static File serviceTagFileHome;
96
private static File serviceTagFileNb;
99
private static File nbClusterDir;
102
private static File nbInstallDir;
104
/** File in home dir */
105
private static File regXmlFileHome;
107
/** File in install dir */
108
private static File regXmlFileNb;
110
private static RegistrationData registration;
112
private static final Logger LOG = Logger.getLogger("org.netbeans.modules.reglib.NbServiceTagSupport"); // NOI18N
114
private static File registerHtmlParent;
116
private final static String REGISTRATION_HTML_NAME = "register";
118
private static boolean inited = false;
120
private static void init () {
121
LOG.log(Level.FINE,"Initializing");
122
NB_CLUSTER = NbBundle.getMessage(NbServiceTagSupport.class,"nb.cluster");
123
NB_VERSION = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.nb.version");
124
GF_VERSION = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.gf.version");
126
//This return platfomX dir but we need install dir
127
File f = new File(System.getProperty("netbeans.home"));
129
nbInstallDir = f.getParentFile();
130
LOG.log(Level.FINE,"NetBeans install dir is:" + nbInstallDir);
132
nbClusterDir = new File(nbInstallDir,NB_CLUSTER);
133
LOG.log(Level.FINE,"nb cluster dir is:" + nbClusterDir);
135
svcTagDirNb = new File(nbClusterDir.getPath() + File.separator + ST_DIR);
136
svcTagDirHome = new File(USER_HOME + File.separator + ".netbeans-registration"
137
+ File.separator + NB_VERSION);
138
if (nbClusterDir.canWrite() && (!svcTagDirNb.exists())) {
139
svcTagDirNb.mkdirs();
141
if (!svcTagDirHome.exists()) {
142
svcTagDirHome.mkdirs();
145
regXmlFileNb = new File(svcTagDirNb,REG_FILE);
146
regXmlFileHome = new File(svcTagDirHome,REG_FILE);
148
serviceTagFileNb = new File(svcTagDirNb,ST_FILE);
149
serviceTagFileHome = new File(svcTagDirHome,ST_FILE);
155
* First look in registration data if NetBeans service tag exists.
156
* If not then create new service tag.
158
* @param source client who creates service tag eg.: "NetBeans IDE 6.0.1 Installer"
159
* or "NetBeans IDE 6.0.1"
160
* @param javaVersion IDE will provides java version on which IDE is running ie. value of system
161
* property java.version. Installer will provide java version selected to run IDE
162
* @return service tag instance for NetBeans
163
* @throws java.io.IOException
165
public static ServiceTag createNbServiceTag (String source, String javaVersion) throws IOException {
169
LOG.log(Level.FINE,"Creating NetBeans service tag");
171
ServiceTag st = getNbServiceTag();
173
if ((serviceTagFileNb.exists() || serviceTagFileHome.exists())) {
175
"NetBeans service tag is already created and saved in registration.xml");
178
LOG.log(Level.FINE,"NetBeans service tag is already created");
182
// New service tag entry if not created
184
LOG.log(Level.FINE,"Creating new service tag");
185
st = newNbServiceTag(source, javaVersion);
186
// Add the service tag to the registration data in NB
187
getRegistrationData().addServiceTag(st);
188
writeRegistrationXml();
191
// Install a system service tag if supported
192
if (Registry.isSupported()) {
193
LOG.log(Level.FINE,"Add service tag to system registry");
194
installSystemServiceTag(st);
196
LOG.log(Level.FINE,"Cannot add service tag to system registry as ST infrastructure is not found");
202
* First look in registration data if GlassFish tag exists.
203
* If not then create new service tag.
204
* @return service tag instance for GlassFish
205
* @throws java.io.IOException
207
public static ServiceTag createGfServiceTag
208
(String source, String jdkHomeUsedByGlassfish, String jdkVersionUsedByGlassfish, String glassfishHome) throws IOException {
212
LOG.log(Level.FINE,"Creating GlassFish service tag");
214
ServiceTag st = getGfServiceTag();
216
if ((serviceTagFileNb.exists() || serviceTagFileHome.exists())) {
218
"GlassFish service tag is already created and saved in registration.xml");
221
LOG.log(Level.FINE,"GlassFish service tag is already created");
225
// New service tag entry if not created
227
LOG.log(Level.FINE,"Creating new GlassFish service tag");
228
st = newGfServiceTag(source, jdkHomeUsedByGlassfish, jdkVersionUsedByGlassfish, glassfishHome);
229
// Add the service tag to the registration data in NB
230
getRegistrationData().addServiceTag(st);
231
writeRegistrationXml();
238
* Used to transfer service tag from GF to NB.
239
* First look in registration data if GlassFish tag exists and is
240
* different then replace it by passed parameter.
241
* @return service tag instance for GlassFish
242
* @throws java.io.IOException
244
public static ServiceTag createGfServiceTag (ServiceTag serviceTag) throws IOException {
248
LOG.log(Level.FINE,"Creating GlassFish service tag");
250
ServiceTag st = getGfServiceTag();
252
//If GF service tag already exists replace it with passed instance
253
if (!st.equals(serviceTag)) {
254
//First remove existing
255
getRegistrationData().removeServiceTag(st.getInstanceURN());
256
getRegistrationData().addServiceTag(serviceTag);
257
writeRegistrationXml();
260
getRegistrationData().addServiceTag(serviceTag);
261
writeRegistrationXml();
267
* First look in registration data if JDK tag exists.
268
* If not then create new service tag. This method must be called from correct JDK.
269
* @return service tag instance for JDK
270
* @throws java.io.IOException
272
public static ServiceTag createJdkServiceTag (String source) throws IOException {
276
LOG.log(Level.FINE,"Creating JDK service tag");
278
ServiceTag st = getJdkServiceTag();
280
if ((serviceTagFileNb.exists() || serviceTagFileHome.exists())) {
282
"JDK service tag is already created and saved in registration.xml");
285
LOG.log(Level.FINE,"JDK service tag is already created");
289
// New service tag entry if not created
291
LOG.log(Level.FINE,"Creating new JDK service tag");
292
st = ServiceTag.getJavaServiceTag(source);
293
// Add the service tag to the registration data in NB
294
getRegistrationData().addServiceTag(st);
295
writeRegistrationXml();
298
//Do not save JDK service tag to system registry as call ServiceTag.getJavaServiceTag(source)
304
* Write the registration data to the registration.xml file
305
* @throws java.io.IOException
307
private static void writeRegistrationXml() throws IOException {
308
File targetFile = null;
309
if (svcTagDirNb.exists() && svcTagDirNb.canWrite()) {
310
//Try to create temp file to verify we can create file on Windows
313
tmpFile = File.createTempFile("regtmp", null, svcTagDirNb);
314
} catch (IOException exc) {
315
LOG.log(Level.INFO,"Warning: Cannot create file in " + svcTagDirNb
316
+ " Will use user home dir", exc);
318
if ((tmpFile != null) && tmpFile.exists()) {
320
targetFile = regXmlFileNb;
322
targetFile = regXmlFileHome;
325
targetFile = regXmlFileHome;
327
BufferedOutputStream out = null;
329
out = new BufferedOutputStream(new FileOutputStream(targetFile));
330
getRegistrationData().storeToXML(out);
331
} catch (IOException ex) {
333
"Error: Cannot save registration data to \"" + targetFile + "\":" + ex.getMessage());
343
* Returns the NetBeans registration data located in
344
* the NB_INST_DIR/nb6.0/servicetag/registration.xml by default.
346
* @throws IllegalArgumentException if the registration data
347
* is of invalid format.
349
public static RegistrationData getRegistrationData () throws IOException {
353
if (registration != null) {
358
if (regXmlFileNb.exists()) {
359
srcFile = regXmlFileNb;
360
LOG.log(Level.FINE,"Service tag will be loaded from NB install dir: " + srcFile);
361
} else if (regXmlFileHome.exists()) {
362
srcFile = regXmlFileHome;
363
LOG.log(Level.FINE,"Service tag will be loaded from user home dir: " + srcFile);
365
registration = new RegistrationData();
366
LOG.log(Level.FINE,"Service tag file not found");
370
BufferedInputStream in = null;
372
in = new BufferedInputStream(new FileInputStream(srcFile));
373
registration = RegistrationData.loadFromXML(in);
374
} catch (IOException ex) {
375
LOG.log(Level.INFO,"Error: Bad registration data \"" +
376
srcFile + "\":" + ex.getMessage());
387
* Create new service tag instance for NetBeans
388
* @param svcTagSource
390
* @throws java.io.IOException
392
private static ServiceTag newNbServiceTag (String svcTagSource, String javaVersion) throws IOException {
393
// Determine the product URN and name
394
String productURN, productName, parentURN, parentName;
396
productURN = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.nb.urn");
397
productName = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.nb.name");
399
parentURN = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.nb.parent.urn");
400
parentName = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.nb.parent.name");
402
return ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
408
getNbProductDefinedId(javaVersion),
410
System.getProperty("os.arch"),
416
* Create new service tag instance for GlassFish
417
* @param svcTagSource
419
* @throws java.io.IOException
421
private static ServiceTag newGfServiceTag
422
(String svcTagSource, String jdkHomeUsedByGlassfish, String jdkVersionUsedByGlassfish, String glassfishHome) throws IOException {
423
// Determine the product URN and name
424
String productURN, productName, parentURN, parentName;
426
productURN = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.gf.urn");
427
productName = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.gf.name");
429
parentURN = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.gf.parent.urn");
430
parentName = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.gf.parent.name");
432
return ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
438
getGfProductDefinedId(jdkHomeUsedByGlassfish, jdkVersionUsedByGlassfish, glassfishHome),
439
"Sun Microsystems Inc.",
440
System.getProperty("os.arch"),
446
* Return the NetBeans service tag from local registration data.
447
* Return null if srevice tag is not found.
449
* @return a service tag for
451
private static ServiceTag getNbServiceTag () throws IOException {
452
String productURN = NbBundle.getMessage(NbServiceTagSupport.class,"servicetag.nb.urn");
453
RegistrationData regData = getRegistrationData();
454
Collection<ServiceTag> svcTags = regData.getServiceTags();
455
for (ServiceTag st : svcTags) {
456
if (productURN.equals(st.getProductURN())) {
464
* Return the GlassFish service tag from local registration data.
465
* Return null if service tag is not found.
467
* @return a service tag for
469
private static ServiceTag getGfServiceTag () throws IOException {
470
RegistrationData regData = getRegistrationData();
471
Collection<ServiceTag> svcTags = regData.getServiceTags();
472
for (ServiceTag st : svcTags) {
473
if (st.getProductName().startsWith("Sun Java System Application Server")) {
481
* Return the JDK service tag from local registration data.
482
* Return null if service tag is not found.
484
* @return a service tag for
486
private static ServiceTag getJdkServiceTag () throws IOException {
487
RegistrationData regData = getRegistrationData();
488
Collection<ServiceTag> svcTags = regData.getServiceTags();
489
for (ServiceTag st : svcTags) {
490
if (st.getProductName().startsWith("J2SE") || st.getProductName().startsWith("Java SE")) {
498
* Returns the product defined instance ID for NetBeans IDE.
499
* It is a list of comma-separated name/value pairs:
500
* "id=<full-version>"
501
* "dir=<NetBeans install dir>"
503
* where <full-version> is the full version string of the NetBeans IDE,
505
* Example: "id=6.0,dir=/home/mslama/netbeans-6.0"
507
* The "dir" property is included in the service tag to enable
508
* the Service Tag software to determine if a service tag for
509
* NetBeans IDE is invalid and perform appropriate service tag
510
* cleanup if necessary. See RFE# 6574781 Service Tags Enhancement.
513
private static String getNbProductDefinedId (String javaVersion) {
514
StringBuilder definedId = new StringBuilder();
515
definedId.append("id=");
516
definedId.append(NB_VERSION);
518
String location = ",dir=" + nbInstallDir.getPath() + ",java.version=" + javaVersion;
519
if ((definedId.length() + location.length()) < 256) {
520
definedId.append(location);
522
// if it exceeds the limit, we will not include the location
523
LOG.log(Level.INFO, "Warning: Product defined instance ID exceeds the field limit:");
526
return definedId.toString();
530
* Returns the product defined instance ID for GlassFish.
531
* It is a list of comma-separated name/value pairs.
533
* Example: "os.name=Linux;os.version=2.6.22-14-generic;java.version=1.5.0_14;glassfish.home=/home/mslama/glassfish;java.home=/usr/java/jdk1.5.0_14/jre"
535
* Caller (installer) must make sure that system property glassfish.home is set.
538
private static String getGfProductDefinedId
539
(String jdkHomeUsedByGlassfish, String jdkVersionUsedByGlassfish, String glassfishHome) {
540
StringBuilder definedId = new StringBuilder();
542
definedId.append("os.name=");
543
definedId.append(System.getProperty("os.name"));
545
definedId.append(",os.version=");
546
definedId.append(System.getProperty("os.version"));
548
definedId.append(",java.version=");
549
definedId.append(jdkVersionUsedByGlassfish);
551
definedId.append(",glassfish.home=");
552
definedId.append(glassfishHome);
554
definedId.append(",java.home=");
555
definedId.append(jdkHomeUsedByGlassfish);
557
return definedId.toString();
561
* Return the zonename if zone is supported; otherwise, return
564
private static String getZoneName() throws IOException {
565
String zonename = "global";
567
String command = "/usr/bin/zonename";
568
File f = new File(command);
569
// com.sun.servicetag package has to be compiled with JDK 5 as well
570
// JDK 5 doesn't support the File.canExecute() method.
571
// Risk not checking isExecute() for the zonename command is very low.
573
ProcessBuilder pb = new ProcessBuilder(command);
574
Process p = pb.start();
575
String output = Util.commandOutput(p);
576
if (p.exitValue() == 0) {
577
zonename = output.trim();
585
* Returns the instance urn stored in the servicetag file
586
* or empty string if file not exists.
588
private static String getInstalledURN() throws IOException {
589
if (serviceTagFileNb.exists() || serviceTagFileHome.exists()) {
591
if (serviceTagFileNb.exists()) {
592
srcFile = serviceTagFileNb;
593
} else if (serviceTagFileHome.exists()) {
594
srcFile = serviceTagFileHome;
596
BufferedReader in = null;
598
in = new BufferedReader(new FileReader(srcFile));
599
String urn = in.readLine().trim();
610
private static void installSystemServiceTag(ServiceTag st) throws IOException {
611
if (getInstalledURN().length() > 0) {
613
LOG.log(Level.INFO, "ST is already installed ie. we have file servicetag.");
618
if (svcTagDirNb.exists() && svcTagDirNb.canWrite()) {
619
//Try to create temp file to verify we can create file on Windows
622
tmpFile = File.createTempFile("regtmp", null, svcTagDirNb);
623
} catch (IOException exc) {
624
LOG.log(Level.INFO,"Error: Cannot create file in " + svcTagDirNb
625
+ " Will use user home dir", exc);
627
if ((tmpFile != null) && tmpFile.exists()) {
629
targetFile = serviceTagFileNb;
631
targetFile = serviceTagFileHome;
634
targetFile = serviceTagFileHome;
637
if (Registry.isSupported()) {
638
//Check if given service tag is already installed in system registry
639
if ((Registry.getSystemRegistry().getServiceTag(st.getInstanceURN()) != null)) {
640
LOG.log(Level.FINE,"Service tag: " + st.getInstanceURN()
641
+ " is already installed in system registry.");
644
//Install in the system ST registry
645
Registry.getSystemRegistry().addServiceTag(st);
647
// Write the instance_run to the servicetag file
648
BufferedWriter out = null;
650
LOG.log(Level.FINE,"Creating file: " + targetFile);
651
out = new BufferedWriter(new FileWriter(targetFile));
652
out.write(st.getInstanceURN());
659
//For NB 6.0 save file 'servicetag' to user dir to avoid creating new ST
660
//by code in IDE launcher
661
if ("6.0".equals(NB_VERSION)) {
662
targetFile = new File(USER_DIR + File.separator + ST_FILE);
664
LOG.log(Level.FINE,"Creating file: " + targetFile + " Specific for 6.0.");
665
out = new BufferedWriter(new FileWriter(targetFile));
666
out.write(st.getInstanceURN());
677
private static File getRegisterHtmlParent() {
678
if (registerHtmlParent == null) {
679
// Determine the location of the offline registration page
680
registerHtmlParent = svcTagDirHome;
682
return registerHtmlParent;
685
/** This should be called after method init is invoked. */
686
public static File getServiceTagDirHome () {
690
return svcTagDirHome;
694
* Returns the File object of the offline registration page localized
695
* for the default locale in the $HOME/.netbeans-registration/$NB_VERSION.
697
public static File getRegistrationHtmlPage(String product, String [] productNames) throws IOException {
702
File parent = getRegisterHtmlParent();
704
File f = new File(parent, REGISTRATION_HTML_NAME + ".html");
705
// Generate the localized version of the offline registration Page
706
generateRegisterHtml(parent,product,productNames);
711
// Remove the offline registration pages
712
private static void deleteRegistrationHtmlPage() {
713
File parent = getRegisterHtmlParent();
714
if (parent == null) {
718
String name = REGISTRATION_HTML_NAME;
719
File f = new File(parent, name + ".html");
725
private static final String NB_HEADER_PNG_KEY = "@@NB_HEADER_PNG@@";
726
private static final String PRODUCT_KEY = "@@PRODUCT@@";
727
private static final String REGISTRATION_URL_KEY = "@@REGISTRATION_URL@@";
728
private static final String REGISTRATION_PAYLOAD_KEY = "@@REGISTRATION_PAYLOAD@@";
730
@SuppressWarnings("unchecked")
731
private static void generateRegisterHtml(File parent, String product, String [] productNames) throws IOException {
732
RegistrationData regData = getRegistrationData();
733
String registerURL = NbConnectionSupport.getRegistrationURL(
734
regData.getRegistrationURN(), product).toString();
736
//Extract image from jar
737
String resource = "/org/netbeans/modules/reglib/resources/nb_header.png";
738
File img = new File(svcTagDirHome, "nb_header.png");
739
String headerImageSrc = img.toURI().toURL().toString();
740
InputStream in = NbServiceTagSupport.class.getResourceAsStream(resource);
742
// if the resource file is missing
743
LOG.log(Level.FINE,"Missing resource file: " + resource);
745
LOG.log(Level.FINE,"Generating " + img + " from " + resource);
746
BufferedInputStream bis = new BufferedInputStream(in);
747
FileOutputStream fos = new FileOutputStream(img);
750
while ((c = bis.read()) != -1) {
762
// Format the registration data in one single line
763
String xml = regData.toString();
764
String lineSep = System.getProperty("line.separator");
765
String payload = xml.replaceAll("\"", "%22").replaceAll(lineSep, " ");
767
String name = REGISTRATION_HTML_NAME;
768
File f = new File(parent, name + ".html");
771
Locale l = Locale.getDefault();
772
Locale [] locales = new Locale[] {
773
new Locale(l.getLanguage(), l.getCountry(), l.getVariant()),
774
new Locale(l.getLanguage(), l.getCountry()),
775
new Locale(l.getLanguage()),
778
for (Locale locale : locales) {
779
resource = "/org/netbeans/modules/reglib/resources/register" + (locale.toString().equals("") ? "" : ("_" + locale)) + ".html";
780
LOG.log(Level.FINE,"Looking for html in: " + resource);
781
in = NbServiceTagSupport.class.getResourceAsStream(resource);
786
LOG.log(Level.FINE,"Found html in: " + resource);
787
LOG.log(Level.FINE,"Generating " + f);
789
BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
790
PrintWriter pw = new PrintWriter(f,"UTF-8");
792
String productName = "";
793
for (int i = 0; i < productNames.length; i++) {
796
" " + NbBundle.getMessage(NbServiceTagSupport.class,"MSG_junction") + " ";
798
productName += "<strong>" + productNames[i] + "</strong>";
800
while ((line = reader.readLine()) != null) {
801
String output = line;
802
if (line.contains(PRODUCT_KEY)) {
803
output = line.replace(PRODUCT_KEY, productName);
804
} else if (line.contains(NB_HEADER_PNG_KEY)) {
805
output = line.replace(NB_HEADER_PNG_KEY, headerImageSrc);
806
} else if (line.contains(REGISTRATION_URL_KEY)) {
807
output = line.replace(REGISTRATION_URL_KEY, registerURL);
808
} else if (line.contains(REGISTRATION_PAYLOAD_KEY)) {
809
output = line.replace(REGISTRATION_PAYLOAD_KEY, payload);