IDL Compiler

May 9th, 2011 | Yazar: Özcan Acar | Kategori: Püf Noktası

Bu aralar bir Corba projesinde çalışıyorum. Corba teknolojisinde interface tanımlama dili olarak IDL kullanılıyor. Eğer bir Corba servisine erişimi sağlamak için size bir IDL verildi ise, bu IDL´i kullanarak client sınıflarını oluşturabilirsiniz. Bu işlem için aşağidaki sınıfı oluşturdum.

Bu implementasyon Sun JDK bünyesinde bulunan com.sun.tools.corba.se.idl.toJavaPortable.Compile ve IBM JDK bünyesinde bulunan com.ibm.idl.toJavaPortable.Compile sınıflarını kullanarak client sınıflarını oluşturuyor. Bu iki sınıf JDK lib dizini altındaki tools.jar içinde yer alıyor. Sınıfın bulunabilmesi için -Djava.home= parametresinin tanımlanmasi gerekiyor. JDK bin dizininde yer alan idlj komutu ile aynı işlemi gerçekleştirebilirsiniz.


/**
 * 
 * @author F520947 Oezcan Acar
 *
 */
public interface IdlToJavaGeneratorService
{
	void generate( String workingDir, String idlFile, String outputDirectroy );
}



import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.plexus.util.StringOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.csg.cs.testing.common.CommonConstants;
import com.csg.cs.testing.generator.GeneratorException;
import com.csg.cs.testing.project.ProjectDirectoryUtils;
import com.csg.cs.testing.service.logger.ILogger;

/**
 * 
 * @author F520947 Oezcan Acar
 *
 */
@Component
final class DefaultIdlToJavaGeneratorServiceImpl implements IdlToJavaGeneratorService
{
	
	@Autowired
	private ILogger logger;
	
	@Autowired
	private IIdlParserService parser;
	
	
	@Override
	public void generate( final String inputDirectory, final String idlFile, final String outputDirectory)
	{
		
		File idl = new File( ProjectDirectoryUtils.getWorkingDirRoot() + "/" + idlFile );
		List< String > includes = parser.getIdlIncludes( idl );
		
		List<String> args = new ArrayList< String >();

		args.add( "-emitAll" );
        args.add( "-fclient" );
        args.add( "-pkgPrefix" );
        
        String interfaceName = parser.getRealInterface( idl );
        args.add( interfaceName );
        args.add( CommonConstants.SERVICE_PACKAGE );
        
        for (String include : includes)
		{
        	args.add( "-pkgPrefix" );
            args.add( include );
            args.add( CommonConstants.SERVICE_PACKAGE );
		}
        
        List< String > baseInterfaces = parser.getBaseInterfaces( idl );
        for (String base : baseInterfaces)
		{
        	args.add( "-pkgPrefix" );
            args.add( base );
            args.add( CommonConstants.SERVICE_PACKAGE );
		}
        
        args.add( "-pkgPrefix" );
        args.add( "CS_Inquiry_0_0" );
        args.add( CommonConstants.SERVICE_PACKAGE );
        
        args.add( "-pkgPrefix" );
        args.add( "CS_Inquiry_0_0Operations" );
        args.add( CommonConstants.SERVICE_PACKAGE );
        
        args.add( "-i" );
        args.add( inputDirectory );
        args.add( "-td" );
        args.add( outputDirectory );
        args.add( idlFile );
        

        Class<?> compilerClass = getCompilerClass();
        invokeCompiler( compilerClass, args );
	}
	
	private Class<?> getCompilerClass()
	{
		ClassLoader cl = this.getClass().getClassLoader();
		Class<?> idljCompiler;
		try
		{
			idljCompiler = Class.forName(getIDLCompilerClass());
		} 
		catch (ClassNotFoundException e)
		{
			try
			{
				File javaHome = new File(System.getProperty("java.home"));
				logger.log("java.home=" + javaHome);
				logger.log("tools.har=" + javaHome+"/lib/tools.jar");
				
				File toolsJar = new File(javaHome, "/lib/tools.jar");
				URL toolsJarUrl = toolsJar.toURL();
				URLClassLoader urlLoader = new URLClassLoader(new URL[]
				{ toolsJarUrl }, cl);

				// Unfortunately the idlj compiler reads messages using the
				// system class path.
				// Therefore this really nasty hack is required.
				System.setProperty("java.class.path",System.getProperty("java.class.path")+ System.getProperty("path.separator")+ toolsJar.getAbsolutePath());
				if (System.getProperty("java.vm.name").indexOf("HotSpot") != -1)
				{
					urlLoader.loadClass("com.sun.tools.corba.se.idl.som.cff.FileLocator");
				}
				idljCompiler = urlLoader.loadClass(getIDLCompilerClass());
			} 
			catch (Exception notUsed)
			{
				throw new GeneratorException(notUsed);
			}
		}
		return idljCompiler;
	}
	
	
	
	private String getIDLCompilerClass()
    {
        String vendor = System.getProperty( "java.vm.vendor" );

        if ( vendor.indexOf( "IBM" ) != -1 )
        {
            return "com.ibm.idl.toJavaPortable.Compile";
        }
        return "com.sun.tools.corba.se.idl.toJavaPortable.Compile";
    }
	
	
	private void invokeCompiler( final Class<?> compilerClass, final List<String> args)
	{
		logger.log("Current dir : " + System.getProperty("user.dir"));
		Method compilerMainMethod;
		String arguments[];

		args.add(0, "-verbose");
		arguments = (String[]) args.toArray(new String[args.size()]);
		String command = compilerClass.getName();
		for (int i = 0; i < arguments.length; i++)
		{
			command += " " + arguments[i];
		}
		logger.log(command);

		try
		{
			compilerMainMethod = compilerClass.getMethod("main", new Class[] { String[].class });
		} 
		catch (NoSuchMethodException e1)
		{
			throw new GeneratorException("Error: Compiler had no main method");
		}

		int exitCode = 0;
		// Backup std channels
		PrintStream stdErr = System.err;
		PrintStream stdOut = System.out;
		// Local channels
		StringOutputStream err = new StringOutputStream();
		StringOutputStream out = new StringOutputStream();
		System.setErr(new PrintStream(err));
		System.setOut(new PrintStream(out));
		try
		{
			Object retVal = (Object) compilerMainMethod.invoke(compilerClass,new Object[]{ arguments });
			if (retVal != null &amp;amp;amp;amp;&amp;amp;amp;amp; retVal instanceof Integer)
				exitCode = ((Integer) retVal).intValue();

		} 
		catch (InvocationTargetException e)
		{
			throw new GeneratorException(e);
		} 
		catch (Throwable e)
		{	
			e.printStackTrace();
			throw new GeneratorException("IDL compilation failed");
		} 
		finally
		{
			if (!"".equals(out.toString()))		logger.log(out.toString());
			if (!"".equals(err.toString()))		logger.log(err.toString());
			// Restore std channels
			System.setErr(stdErr);
			System.setOut(stdOut);
		}
	}

}



EOF ( End Of Fun )
Özcan Acar



Püf Noktası kategorisinden son yazılar

Share Button

Özcan Acar

Bilgisayar mühendisi olan Özcan Acar 1997 yılından beri programcı olarak çalışıyor.

KurumsalJava.com, SmartHomeProgrammer.com ve Mikrodevre.com adresleri altında blog yazıyor. Kurduğu BTSoru.com'da ona yazılımla ile ilgili sorularınızı yöneltebilirsiniz. Pratik Programcı Yayınları bünyesinde Pratik Spring, Pratik Agile, Pratik Git ve Design Patterns ismini taşıyan kitapları bulunmaktadır. 21.12.2009 tarihinde Java Champion olarak seçildi.
  • Share/Bookmark
1 yorum | 6.714 kez okundu |

1 Yıldız2 Yıldız3 Yıldız4 Yıldız5 Yıldız (1 değerlendirme, ortalama: 1, toplam oy 5)
Loading ... Loading ...
Tags: ,

1 YORUM “IDL Compiler”

  1. Alihan diyor ki:

    Bu koda bi Builder pattern yakisirdi ! :(

BU YAZI İÇİN BİR YORUM YAPABİLİRSİNİZ.