/* * Copyright 2008 Niclas Hedhman. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package org.qi4j.library.jini.lookup; import com.sun.jini.admin.DestroyAdmin; import com.sun.jini.start.NonActivatableServiceDescriptor; import net.jini.admin.Administrable; import net.jini.config.Configuration; import net.jini.config.EmptyConfiguration; import org.qi4j.api.common.Optional; import org.qi4j.api.injection.scope.Service; import org.qi4j.api.injection.scope.This; import org.qi4j.api.service.Activatable; import org.qi4j.library.http.HttpService; import org.qi4j.library.http.Interface; import java.io.*; import java.net.UnknownHostException; import java.security.Policy; import java.util.ArrayList; import java.util.StringTokenizer; public class ReggieMixin implements Activatable { @Optional @Service HttpService httpService; @This org.qi4j.api.configuration.Configuration<ReggieConfiguration> my; private NonActivatableServiceDescriptor.Created lookupCreated; private File fileToCleanup; public void activate() throws Exception { // Prepare a temporary directory. File qi4j = new File( "qi4jtemp" ); qi4j.mkdir(); fileToCleanup = qi4j.getAbsoluteFile(); File jini = new File( qi4j, "jini" ); jini.mkdirs(); File temp = File.createTempFile( "reggie", "", jini ); temp.delete(); boolean success = temp.mkdirs(); // Start Reggie Configuration serviceDescConfig = EmptyConfiguration.INSTANCE; String httpURL = my.configuration().reggieDlJarLocation().get(); if( httpURL == null ) { // If Http Service not running in this JVM, we need the Download URL from configuration. if( httpService != null ) { httpURL = constructDownloadURL(); } } String reggieJarLocation = createReggieJars( temp ); File reggieJarFile = new File( reggieJarLocation ); String securityPolicyLocation = createSecurityPolicy( temp, reggieJarFile ); String reggieConfig = createReggieConfig( temp ); System.out.println( "Policy: " + Policy.getPolicy() ); NonActivatableServiceDescriptor serviceDescriptor = new NonActivatableServiceDescriptor( httpURL, securityPolicyLocation, reggieJarLocation, "com.sun.jini.reggie.TransientRegistrarImpl", new String[]{ reggieConfig } ); lookupCreated = (NonActivatableServiceDescriptor.Created) serviceDescriptor.create( serviceDescConfig ); } public void passivate() throws Exception { System.out.println( "Destroying Reggie." ); Object admin = ( (Administrable) lookupCreated.proxy ).getAdmin(); ( (DestroyAdmin) admin ).destroy(); removeFile( fileToCleanup ); } private String createReggieConfig( File dir ) throws IOException { StringBuffer configuration = new StringBuffer(); if( my.configuration().useJrmp().get() ) { System.out.println( "Using JRMP..." ); configuration.append( "import net.jini.jrmp.JrmpExporter;\n" + "\n" + "com.sun.jini.reggie {\n" + "\n" + " serverExporter = new JrmpExporter();\n" ); } else { System.out.println( "Using JERI..." ); configuration.append( "import net.jini.jeri.BasicILFactory;\n" + "import net.jini.jeri.BasicJeriExporter;\n" + "import net.jini.jeri.tcp.TcpServerEndpoint;\n" + "\n" + "com.sun.jini.reggie\n" + "{\n" + " private invocationLayerFactory = new BasicILFactory();\n" + " serverExporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0),\n" + " invocationLayerFactory,\n" + " false,\n" + " true);\n" ); } configuration.append( " initialMemberGroups = new String[] {" ); String groupData = my.configuration().groups().get(); String[] groups; if( groupData != null ) { groups = convert( groupData ); } else { groups = new String[]{ "qi4j" }; } boolean first = true; for( String group : groups ) { if( !first ) { configuration.append( ", " ); } first = false; configuration.append( " \"" ); configuration.append( group ); configuration.append( "\" " ); } configuration.append( "};\n}" ); File reggieConfigFile = new File( dir, "reggie.conf" ); if( !reggieConfigFile.exists() ) { InputStream reggieConfig = new ByteArrayInputStream( configuration.toString().getBytes() ); copyStreamToFile( reggieConfig, reggieConfigFile ); } return reggieConfigFile.getAbsolutePath(); } private String[] convert( String data ) { if( data == null ) { return new String[0]; } ArrayList<String> result = new ArrayList<String>(); StringTokenizer st = new StringTokenizer( data, ",", false ); while( st.hasMoreTokens() ) { String token = st.nextToken(); result.add( token ); } String[] retVal = new String[result.size()]; return result.toArray( retVal ); } private String createReggieJars( File temp ) throws IOException { File reggieJar = new File( temp, "reggie-2.1.1.jar" ); if( !reggieJar.exists() ) { InputStream reggie = getClass().getResourceAsStream( "reggie-2.1.1.jar" ); copyStreamToFile( reggie, reggieJar ); } return reggieJar.getAbsolutePath(); } private void removeFile( File fileToCleanup ) { if( fileToCleanup == null ) { return; } File[] files = fileToCleanup.listFiles(); if( files == null ) { return; } for( File file : files ) { removeFile( file ); } fileToCleanup.delete(); } private String constructDownloadURL() throws UnknownHostException { Interface[] interfaces = httpService.interfacesServed(); String host = interfaces[ 0 ].hostName(); int port = interfaces[ 0 ].port(); String protocol = interfaces[ 0 ].protocol().toString(); return protocol + "://" + host + ":" + port + "/jini/reggie-dl.jar"; } private String createSecurityPolicy( File tempDir, File reggieJarFile ) throws IOException { String securityPolicy = my.configuration().securityPolicy().get(); if( securityPolicy == null || "".equals( securityPolicy ) ) { securityPolicy = "grant { permission java.security.AllPermission; };"; } File securityPolicyFile = new File( tempDir, "reggie-security.policy" ); copyStringToFile( securityPolicy, securityPolicyFile ); return securityPolicyFile.getAbsolutePath(); } private void copyStringToFile( String securityPolicy, File securityPolicyFile ) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream( securityPolicy.getBytes() ); copyStreamToFile( bais, securityPolicyFile ); } private void copyStreamToFile( InputStream inputStream, File destinationFile ) throws IOException { destinationFile = destinationFile.getAbsoluteFile(); File parentFile = destinationFile.getParentFile(); if( !parentFile.exists() ) { parentFile.mkdirs(); } FileOutputStream fos = new FileOutputStream( destinationFile ); Streams.copyStream( inputStream, fos, true ); } }