Monday, November 12, 2012

Install ipa to iOS from commandline

Install ipa to iOS from commandline


using following command:
./transporter_chief.rb ./kulerios.ipa


file can be found at :https://docs.google.com/open?id=0Byq0T4vvPHLHNDJhcmtUcmcxbGM


Wednesday, October 17, 2012

JNI learning: Basic


1, Java app code :

package test.sample.jni.run;

public class Sample {

static int staticint = 0;
String strField="default";
int intField=0;
public native int intMethod(int n);
public native boolean booleanMethod(boolean bool);
public native String stringMethod(String text);
public native int intArrayMethod(int[] intArray);
public native boolean callJavaMethod(String text);
public String callmethod(String c,int  a){

String s = "intput value is "+String.valueOf(a)+":"+c;
System.out.println(s);
return s;
}
public void perf()
{
System.out.println(this.intMethod(5));
boolean bool = this.booleanMethod(true);
this.callJavaMethod("abc");
for(int i=0 ; i<10000;i++)
//System.out.println(this.stringMethod("Java"));
this.callJavaMethod("abc");
int sum = this.intArrayMethod(new int[]{1,2,3,4});
System.out.println(this.strField+":"+this.intField);
}
/**
* @param args
*/
public static void main(String[] args) {
System.loadLibrary("sample");
for(int j= 0 ; j < 10; j++){
new Sample().perf();
}
}
}

2. Native library header file

javah test.sample.jni.run.Sample at bin folder. there will be following .h generated:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class test_sample_jni_run_Sample */

#ifndef _Included_test_sample_jni_run_Sample
#define _Included_test_sample_jni_run_Sample
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     test_sample_jni_run_Sample
 * Method:    intMethod
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_test_sample_jni_run_Sample_intMethod
  (JNIEnv *, jobject, jint);

/*
 * Class:     test_sample_jni_run_Sample
 * Method:    booleanMethod
 * Signature: (Z)Z
 */
JNIEXPORT jboolean JNICALL Java_test_sample_jni_run_Sample_booleanMethod
  (JNIEnv *, jobject, jboolean);

/*
 * Class:     test_sample_jni_run_Sample
 * Method:    stringMethod
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_test_sample_jni_run_Sample_stringMethod
  (JNIEnv *, jobject, jstring);

/*
 * Class:     test_sample_jni_run_Sample
 * Method:    intArrayMethod
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_test_sample_jni_run_Sample_intArrayMethod
  (JNIEnv *, jobject, jintArray);

/*
 * Class:     test_sample_jni_run_Sample
 * Method:    callJavaMethod
 * Signature: (Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_test_sample_jni_run_Sample_callJavaMethod
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

3. Native library 

create one dll project and implement the header file with following c++ file:
//#include "stdafx.h"
#include "test_sample_jni_run_Sample.h"
#include <string.h>

JNIEXPORT jint JNICALL Java_test_sample_jni_run_Sample_intMethod
  (JNIEnv *env, jobject ojb, jint num){
 
 jclass cls = env->GetObjectClass(ojb);
 jfieldID intfid = env->GetFieldID(cls,"intField","I");
 if(intfid)
 {
 jint intvalue = (jint)env->GetObjectField(ojb,intfid);
 printf("intfield value is %d \n", intvalue);
 env->SetIntField(ojb,intfid,100);
 }
 return num * num;
  }
JNIEXPORT jboolean JNICALL Java_test_sample_jni_run_Sample_booleanMethod
  (JNIEnv *env, jobject ojb, jboolean boolean){
    return !boolean;
  }

JNIEXPORT jboolean JNICALL Java_test_sample_jni_run_Sample_callJavaMethod
  (JNIEnv *env, jobject ojb, jstring string){

   jclass cls = env->GetObjectClass(ojb);
 
 jfieldID strfid = env->GetFieldID(cls,"strField","Ljava/lang/String;");
 //call java method
 jmethodID mid = env->GetMethodID(cls,"callmethod","(Ljava/lang/String;I)Ljava/lang/String;");
 if (mid)
 {
 jstring inputS = env->NewStringUTF("from nativefrom nativefrom nativefrom nativefrom nativefrom nativefrom nativefrom native");  
 jint inputV = 1;
 jstring  strvalue = (jstring )env->CallObjectMethod(ojb,mid,inputS,inputV);
 const char *str;
 str = env->GetStringUTFChars(strvalue, 0);
 printf("call java method return value is %s \n", str);
 env->DeleteLocalRef(inputS);
 }
 return true;
}
JNIEXPORT jstring JNICALL Java_test_sample_jni_run_Sample_stringMethod
  (JNIEnv *env, jobject ojb, jstring string){
 
 jclass cls = env->GetObjectClass(ojb);
 
 jfieldID strfid = env->GetFieldID(cls,"strField","Ljava/lang/String;");
 //call java feild
 if(strfid)
 {
 jstring  strvalue = (jstring )env->GetObjectField(ojb,strfid);
 const char *str;
 str = env->GetStringUTFChars(strvalue, 0);
 printf("strField value is %s \n", str);
 strvalue = env->NewStringUTF("from nativefrom nativefrom nativefrom nativefrom nativefrom nativefrom nativefrom native");  
 env->SetObjectField(ojb,strfid,(jobject)strvalue);
 env->DeleteLocalRef(strvalue);
 }

 //call java method
 jmethodID mid = env->GetMethodID(cls,"callmethod","(Ljava/lang/String;I)Ljava/lang/String;");
 if (mid)
 {
 jstring inputS = env->NewStringUTF("from nativefrom nativefrom nativefrom nativefrom nativefrom nativefrom nativefrom native");  
 jint inputV = 1;
 jstring  strvalue = (jstring )env->CallObjectMethod(ojb,mid,inputS,inputV);
 const char *str;
 str = env->GetStringUTFChars(strvalue, 0);
 printf("call java method return value is %s \n", str);
 env->DeleteLocalRef(inputS);
 }


 //return str;

 const char *str = env->GetStringUTFChars(string, 0);
 char cap[128];
 strcpy(cap, str);
 env->ReleaseStringUTFChars(string, str);
 return env->NewStringUTF(strupr(cap));
  }
  
JNIEXPORT jint JNICALL Java_test_sample_jni_run_Sample_intArrayMethod
  (JNIEnv *env, jobject obj, jintArray array) {
    int i, sum = 0;
    jsize len = env->GetArrayLength(array);
    jint *body = env->GetIntArrayElements(array, 0);
    for (i=0; i<len; i++)
    {
      sum += body[i];
    }
    env->ReleaseIntArrayElements(array, body, 0);;// avoid mem leaks
    return sum;
  }
  void main(){}

4. Java call native lib

place the native lib to the class path at Java application run time. and explicitly call system load like this: System.loadLibrary("sample"); //don't add extension.

5.Native Application call Java class

Project setting:
1. link following lib :
C:\Program Files (x86)\Java\jdk1.6.0_11\lib\jvm.lib
2. include following head file:
C:\Program Files (x86)\Java\jdk1.6.0_11\include;C:\Program Files (x86)\Java\jdk1.6.0_11\include\win32
3. add jvm.dll to dll search path by modify environment path :
C:\Program Files (x86)\Java\jdk1.6.0_11\jre\bin\client\jvm.dll


In the following source code, C++ create jvm and call the specified the java class:

#include <jni.h>
#include <string.h>
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif

static jmethodID gmid;

void checkGloabalMethod()
{
}
int main()
{

JavaVMOption options [1];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
jint square;
jboolean not;

options[0].optionString = "-Djava.class.path=.;C:/Users/jiali/Documents/Visual Studio 2010/Projects/sample/Debug";
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);

if (status != JNI_ERR)
{
cls = env->FindClass("CalledbyNative");
if (cls)
{
jfieldID a = env->GetStaticFieldID(cls,"a","I");
if(a)
{
jint avalue = env->GetStaticIntField(cls,a);
printf("field a  value is %d \n",avalue);
}
mid = env->GetStaticMethodID(cls,"intMethod","(I)I");
gmid = (jmethodID)env->NewGlobalRef((jobject)mid);
if (mid)
{
square = env->CallStaticIntMethod(cls,mid,5);
printf("square is %d \n",square);
}
mid = env->GetStaticMethodID(cls, "booleanMethod","(Z)Z");
if(mid)
{
not = env->CallStaticBooleanMethod(cls,mid,1);
printf("Result of booleanmethod is %d \n",not);
}
}
status = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
square = env->CallStaticIntMethod(cls,gmid,6);
printf("square is %d \n",square);
jvm->DestroyJavaVM();
return 0;
}
return -1;
}





Tuesday, October 9, 2012

Tips OSGI and Decompile swf


OSGI:
1,install bundle:
install file:c:\net.adamsoftware.drive_4.0.0.jar
start bundleid

There is one tool called 'swfdump' at flex sdk folder.this tool can be used to show the swf info.

Friday, August 17, 2012

How to import certification to java cacert

1. clicking on the certificate error in your browser to view the certificate. and export the certification  as 1.cer.

2) Import to java cacert:

 keytool -import -trustcacerts -file C:\Users\jiali\Desktop\1\1.cer -keystore
"C:\ProgramData\Adobe\CS5\jre\lib\security\cacerts"
3. Add to Trusted Root Certification Authorities in windows MMC:
To manage trusted root certificates for a local computer
  1. Click Start, click Start Search, type mmc, and then press ENTER.
  2. On the File menu, click Add/Remove Snap-in.
  3. Under Available snap-ins, click Local Group Policy Object Editor,click Add, select the computer whose local Group Policy object (GPO) you want to edit, and then click Finish.
  4. If you have no more snap-ins to add to the console, click OK.
  5. In the console tree, go to Local Computer PolicyComputer ConfigurationWindows SettingsSecurity Settings, and then click Public Key Policies.
  6. Double-click Certificate Path Validation Settings,and thenclick the Stores tab.
  7. Select the Define these policy settings check box.
  8. Under Per user certificate stores, clear the Allow user trusted root CAs to be used to validate certificates and Allow users to trust peer trust certificates check boxes.
  9. Under Root certificate stores, select the root CAs that the client computers can trust, and then click OK to apply the new settings.
    http://technet.microsoft.com/en-us/library/cc754841.aspx
    https://www.globalsign.com/support/intermediate/intermediate_windows.php





After import to java cacert, then CMIS workbench tool can access the SSL server.

Monday, August 13, 2012

Using exec and sed to replace string in files

1. How to unlock files:

find . -exec chflags nouchg {} \;

2. How to replace string in files:

find . */info.xml -type f -exec sed -i '' 's/<\/testcase>/<serverinfo>CQ<\/serverinfo><\/abc>/g' {} \;


3. Rename files in the folder:

find . -name "1.idea*" -exec mv '{}' '{}.idea' \;

Notes: rename all the files start with '1.idea' to append '.idea' at the file name.

Wednesday, August 8, 2012

Check signature and version info on Mac and Windows


Mac:


Following command are very useful: codesign, defauls.


#!/bin/bash
files=(
"/Library/Services/AdobeDrive4.service" "/Volumes/AdobeDrive4-mul/Install.app"
"/Library/Application Support/Adobe/Adobe Drive 4/Adobe Drive.app"
)
echo "-----------------------------------------------------------------codesign -v -ddd -----------------------------------------------------------------"
for file in "${files[@]}"
do
echo "codesign -v -vvv " "$file"
codesign -v -vvv "$file"
done

echo "-----------------------------------------------------------------codesign -d -ddd -----------------------------------------------------------------"

for file in "${files[@]}"
do
echo "codesign -d -vvv " "$file"
codesign -d -vvv "$file"
done

echo "-----------------------------------------------------------------spctl --assess -v -----------------------------------------------------------------"

files=(
"/Volumes/AdobeDrive4-mul/Install.app"
)

for file in "${files[@]}"
do
echo "spctl --assess -v " "$file"
spctl --assess -v "$file"
done

#!/bin/bash

echo "-----------------------------------------------------------------get version -----------------------------------------------------------------"

files=(
"/Library/Application Support/Adobe/Adobe Drive 4/Adobe Drive.app"
)

for file in "${files[@]}"
do
VERSION=`defaults read "$file/Contents/Info" CFBundleShortVersionString`
echo "get file version " "$file" "$VERSION"
done



Win:

Useful commands : powershell -command , and wmic datafile 


import subprocess
import os

ADx86Folder = "C:\\'Program Files (x86)'\\'Common Files'\\Adobe\\'Adobe Drive 4'";
ADx64Folder = "C:\\'Program Files'\\'Common Files'\\Adobe\\'Adobe Drive 4'";
ExpectBuildNumber = "4.0.1.16";


W64BIT = "win64bit";
W32BIT = "win32bit";
Mac    = "osx";

platform = W32BIT;
if os.path.exists("C:\\Program Files (x86)\\"):
    platform = W64BIT;
if os.path.exists("/Volumes/"):
    platform = Mac;

files =[];    
if platform == W32BIT:
    files=["%s\\ADConnect.exe"%(ADx64Folder),
       "%s\\ADFSMenu.dll"%(ADx64Folder),];
    pass
def getSigNatureCommand(filename):
    sCmd = "powershell -command (get-authenticodesignature \"%s\").status -eq 'valid'"%(filename);
    return sCmd;
    pass
def getFileVersionCommand(filename):
    #sCmd = "powershell -command (get-childitem \"%s\").VersionInfo.FileVersion "%(filename);
    sCmd = "wmic datafile where name=\"%s\" get version "%(filename);
    sCmd = sCmd.replace("'","").replace("\\","/").replace("/","\\\\");
    return sCmd;
    pass

def runValidation():
    
    try:
        vResult = False;
        sResult = False;
        result  = True;
        for f in files:
            print f;
            vResult = False;
            callcmd = getFileVersionCommand(f);
            #print callcmd;
            process = subprocess.Popen(callcmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE);
            line = "";
            while process.poll() == None:
                t = process.stdout.readline().strip();
                if t != "":
                    line = t;
                if line == ExpectBuildNumber:
                    vResult = True;
                    print "Version is right,Expect is %s"%(ExpectBuildNumber);
                    break;
                    pass
            if vResult == False:
                print "~~~~~~~~~~~~~~~~~~~~~~:Version is wrong,Expect is %s, Result is %s.~~~~~~~~~~~~~~~~~~~~~~"%(ExpectBuildNumber,line);
                result = False;
                pass
            sResult = False;
            callcmd = getSigNatureCommand(f);
            #print callcmd;
            process = subprocess.Popen(callcmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE);
            [out,error] =process.communicate();
            line = out.strip();
            if line == "True":
                print "Signature is right"
                sResult = True;
                pass
            if sResult == False:
                print "~~~~~~~~~~~~~~~~~~~~~~:Signature is Wrong.~~~~~~~~~~~~~~~~~~~~~~"
                print callcmd;
                print line + str(error);
                result = False;
                pass            
        print "##########################################################";
        if result:
            print "Check result is PASS"
        else:
            print "Check result is Failure"
        print "##########################################################";
    except Exception,e:
        print str(e);
        pass
runValidation();

Thursday, July 26, 2012

Python subprocess.call() and Popen()


import subprocess
#import test
#callcmd = "test.py";
callcmd2 = "AdobePatchInstaller.exe --mode=silent";
callcmd = "full.bat";
callcmdun = "fullun.bat";

def openProcess(callcmd):
   
    try:
        process = subprocess.Popen(callcmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE);
        #print process.communicate();
        print "----------------";
        while process.poll() == None:
            line = process.stdout.readline();
        print "---Exit code is :"+str(process.poll())+"---"
        retcode =  process.poll();
        if retcode == 0:
            print "---install successfully---"
        #print subprocess.check_call(callcmd, shell=True,stderr=subprocess.STDOUT);
    except Exception,e:
        print str(e);
        pass
    #process.stdin.write("send to test from call");
   
    #print "stdoutdata is : "+str(stdoutdata) + ",stderrdata is : "+str(stderrdata);
openProcess(callcmd);

def callProcess(callcmd):
   
    try:
        process = subprocess.call(callcmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE);
        print "---Exit code is :"+str(process)+"---"
        if process== 0:
            print "---install successfully---"

    except Exception,e:
        print str(e);
        pass
    #process.stdin.write("send to test from call");
   
    #print "stdoutdata is : "+str(stdoutdata) + ",stderrdata is : "+str(stderrdata);
callProcess(callcmdun)

Wednesday, June 27, 2012

Javascript and Python communication by socket and eval javascript in PP

Javascript and Python communication by socket and eval javascript in PP


Extendscript code piece:

//#target photoshop
//#target bridge
//#target estoolkit
function doSometing(info)
{
    eval (info);
}    
var flag =true;
var tcp = null;
var demon = true;
function startServer(port) 
{
    tcp = new Socket;
    // listen on port 1234
    //$.writeln ("Chat server listening on port 1234");
    if (tcp.listen (port)) 
    {
            // poll for a new connection
            var connection = pollConnection();
            if (connection != null) 
            {
                   // alert ("Connection from " + connection.host);
                    m_cConnection =  connection;
                   readRequestFromClient();
            }
    }
}

function pollConnection()
{
    alert("pollConnection");
   var connection = null;
   while ((connection =tcp.poll())== null && flag) 
    $.sleep (1000);
   return  connection;
}
function readRequestFromClient()
{
    alert("readRequestFromClient");
    while (flag)
    {
      info = m_cConnection.read();
      alert ("info is :" + info); 
      if (info == "EXIT")
      {
          closeConnection();
          if (demon)
            { 
                var connection = pollConnection();
                if (connection != null) 
                {
                    m_cConnection =  connection;
                    continue;
                  }
            }else
            {
                return;
                
                }
      }
      if (info == "" || info == null)
      {
      $.sleep (500);
      continue;
      }
      
      doSometing(info);
        break;
    }
}
function responseToClient(info)
{
    alert("responseToClient");
  if(m_cConnection != null)
  {
      m_cConnection.writeln(info);
      readRequestFromClient();
     // m_cConnection.close();
     // delete m_cConnection;
  }else{
      alert("m_cConnection == null");
      }
}
function closeConnection()
{
     alert("closeConnection");
  if(m_cConnection != null)
  {
     m_cConnection.close();
     delete m_cConnection;
  }
}    
function stopServer()
{
    flag = false;
}
var m_cConnection = null;
var btPS = new BridgeTalk;
btPS.target = "photoshop";

function runscriptViaPS(script)
{
    alert("runscriptViaPS: "+ script);
    btPS.body = script;
    btPS.onResult = function (resObj)
    {
        alert("runscriptViaPS results: "+resObj.body );
        doc = eval(resObj.body);
        if(doc == false)
        {
            
          responseToClient("Failt to  runscriptViaPS")
        }    
        else
        {
            alert("runscriptViaPS successfully");
          //alert("sendCreateDocoPS successfully");
          responseToClient("runscriptViaPS successfully");
        }
    }
    btPS.send();

}
startServer(1234);

Python code piece:

# Echo server program
import socket
import time                
HOST = '127.0.0.1'                 # Symbolic name meaning the local host
PORT = 1234              # Arbitrary non-privileged port


createDocviaPS = "runscriptViaPS(\" var doc = app.documents.add(800, 600, 2, \\\"docRef\\\", NewDocumentMode.RGB); var r =(doc != null); r.toSource();\")";

saveAsJPGviaPS = "runscriptViaPS(\"var thistimestamp = Math.round(new Date().getTime() / 1000); 
saveFile = new File(\\\"Z:/geometrixx/test/1.jpg\\\" );saveOptions = new JPEGSaveOptions();  saveOptions.embedColorProfile = true;saveOptions.formatOptions = FormatOptions.STANDARDBASELINE;saveOptions.matte = MatteType.NONE;saveOptions.quality = 9;var doc=app.activeDocument.saveAs(saveFile, saveOptions,true,Extension.LOWERCASE);var r =(doc != null); r.toSource();\")";

EXIT = "EXIT";

def startServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while 1:
      data = conn.recv(1024)
      if not data: break
      conn.send(data)
      print 'Received', repr(data);
    conn.close()
    pass
                                                            
def startClient():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT));
    #msg = raw_input().rstrip( '\n' )
    msg = createDocviaPS;
    s.send(msg);
    data = s.recv(1024);
    print 'Received', repr(data);
    #time.sleep(400);
    msg = saveAsJPGviaPS;
    s.send(msg);
    data = s.recv(1024);
    print 'Received', repr(data);
    s.send(EXIT);
    s.close()
    pass
startClient();
""""
# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
"""

Monday, June 18, 2012

Make OSX application by Python script


#!/bin/bash
rm -r findertest.app
mkdir -p findertest.app/Contents/MacOS
cp -r src/* findertest.app/Contents/MacOS
mv findertest.app/Contents/MacOS/run.py findertest.app/Contents/MacOS/findertest
chmod +x findertest.app/Contents/MacOS/findertest
cur=`pwd`
echo $cur

open -a """$cur"/"findertest.app"""

Sunday, April 15, 2012

Equinox Framework

Equinox
The Equinox Framework component is tasked with being a full implementation to the OSGi Core Framework R4 specification. In addition, the Framework component produces launchers, bootstrap infrastructure and application models that facilitate the use of Equinox OSGi in end-user product scenarios.



Framework Projects





OSGi R4 Framework (org.eclipse.osgi)
The main framework project. This includes a set of adaptors and enough function to make a standalone OSGi framework. When built this project produces org.eclispe.osgi.jar.
Java Launcher (org.eclipse.equinox.launcher)
This helps setup the framework classloader and launches the Framework etc. Note: this code used to be included in the startup.jar and has be moved from its old location in the org.eclipse.platform project. See bug 113069 for more details.
Native Launcher (org.eclipse.equinox.executable)
The launcher is the native executable that finds and runs the java launcher org.eclipse.equinox.launcher and thus the framework. It is also responsible for putting up the splash screen etc. The launcher is written in C and currently supports a wide range of operating systems, window systems and processor architectures. The launcher is split into a small native executable and a platform specific library. The source for both the launcher and the library can be found in the org.eclipse.equinox.executable project.



Equinox_Launcher@Wiki


You can start Eclipse by running eclipse.exe on Windows or eclipse on other platforms. This small launcher essentially finds and loads the JVM. On Windows, the eclipsec.exe console executable can be used for improved command line behavior.
Alternatively, you can launch Eclipse by directly invoking the JVM as follows:
   java -jar eclipse/plugins/org.eclipse.equinox.launcher_1.0.0.v20070606.jar

Find the JVM

If a JVM is installed in the eclipse/jre directory, Eclipse will use it; otherwise the launcher will consult the eclipse.ini file and the system path variable. Eclipse DOES NOT consult the JAVA_HOMEenvironment variable.
To explicitly specify a JVM of your choice, you can use the -vm command line argument:
   eclipse -vm c:\jre\bin\javaw.exe              ''start Java by executing the specified java executable
   eclipse -vm c:\jre\bin\client\jvm.dll         ''start Java by loading the jvm in the eclipse process
See the launcher page for more details on specifying a JVM.

Starting Eclipse Commandline With Equinox Launcher

Ant Script

<!-- set path to eclipse folder. If local folder, use '.'; otherwise, use c:\path\to\eclipse or /path/to/eclipse/ -->
  <property name="eclipse.home" value="."/>
 
  <nowiki><!--  get path to equinox jar inside ${eclipse.home} folder (copy/rename actual jar) --></nowiki>
  <copy tofile="''${eclipse.home}''/eclipse/plugins/org.eclipse.equinox.launcher.jar">
    <fileset dir="''${eclipse.home}''/eclipse/plugins"
      includes="**/org.eclipse.equinox.launcher_*.jar"/>
  </copy>
 
  <nowiki><!-- start Eclipse w/ java --></nowiki>
  <java classpath="''${eclipse.home}''/eclipse/plugins/org.eclipse.equinox.launcher.jar"
  .../>
Or, if you are using Ant 1.7 and don't like copying resources around (or don't have permission to do so) this appears to work to set the path to the newest available equinox launcher jar in a property for later use:
<!-- set path to eclipse folder. If local folder, use '.'; otherwise, use c:\path\to\eclipse or /path/to/eclipse/ -->
  <property name="eclipse.home" value="."/>
 
  <!-- store path to newest launcher JAR in path id 'newest.equinox.launcher.path.id' -->
  <path id="newest.equinox.launcher.path.id">
    <first count="1">
      <sort>
        <fileset dir="${eclipse.home}/eclipse/plugins" includes="**/org.eclipse.equinox.launcher_*.jar"/>
 
        <nowiki><!-- Seems the default order is oldest >
 newest so we must reverse it.
            The 'reverse' and 'date' comparators are in the internal antlib
            org.apache.tools.ant.types.resources.comparators.
         --></nowiki>
        <reverse xmlns="antlib:org.apache.tools.ant.types.resources.comparators">
          <nowiki><!-- 'date' inherits 'reverse's namespace --></nowiki>
          <date/>
        </reverse>
      </sort>
    </first>
  </path>
 
  <!-- turn the path into a property -->
  <property name="equinox.launcher.jar.location" refid="newest.equinox.launcher.path.id" />
 
  <!-- you can now reference the jar through the property ${equinox.launcher.jar.location} -->
  <echo message="Using equinox launcher jar: ${equinox.launcher.jar.location}" />

Bash Shell Script

 #!/bin/bash

 # set path to eclipse folder. If the same folder as this script, use the default; otherwise, use /path/to/eclipse/
 eclipsehome=`dirname $BASH_SOURCE`;

 # get path to equinox jar inside $eclipsehome folder
 cp=$(find $eclipsehome -name "org.eclipse.equinox.launcher_*.jar" | sort | tail -1);

 # start Eclipse w/ java
 /opt/java50/bin/java -cp $cp org.eclipse.equinox.launcher.Main ...

Cmd/Bat Script

Save this as eclipse.cmd. This has been tested with Windows XP Pro (SP2).
 @echo off

 :: set path to eclipse folder. If local folder, use '.'; otherwise, use c:\path\to\eclipse
 set ECLIPSEHOME=.
 
 :: get path to equinox jar inside ECLIPSEHOME folder
 for /f "delims= tokens=1" %%c in ('dir /B /S /OD %ECLIPSEHOME%\plugins\org.eclipse.equinox.launcher_*.jar') do set EQUINOXJAR=%%c
 
 :: start Eclipse w/ java
 echo Using %EQUINOXJAR% to start up Eclipse...
 java -jar %EQUINOXJAR% ...

Monday, April 9, 2012

APE DOM Extensions Overview

1. Introduction

Before CS5, the communication between an ActionScript program running in a Flash Player instance embedded in an application and the application itself was limited to ActionScript's ExternalInterface class. This class offered a XML-based communications protocol to exchange data between the ActionScript world and the application it was embedded in. The application had to write C++ code to use the interface on its side.

This way, an ActionScript program and its embedding host could exchange simple data, such as strings and numbers. But the only realistic way to exchange Live Objects, like a Document object, is through heavy administration and maintenance of several layers of code. Bernd Paradies' PatchPanel technology provided such a layer.

These limitations kept integrators from embedding a Flash Player in an application that was able to efficiently talk to the application's scripting object model.

The APE DOM Extensions are implemented in the APE library. The API is not present in the Flash Player library, or browser plug-in. SWF files that work with DOM Extensions cannot be loaded into a browser environment; they can only load and run in the APE environment.


2. The APIs



Most of the APIs are symmetric. The host has a set of APIs to access the ActionScript object model in an embedded Flash Player instance. Typical calls include the reading and writing of object properties, or the invocation of an object method.
The host application registers a set of function pointers. Again, there are functions to read or write object properties, or to invoke an object method, this time for a host object.
Before working with host or ActionScript objects, there must be a way to get such an object. In a scripting environment, there are several ways.
Access a DOM tree: Often, a host's object model is organized as a tree of objects, starting from a root object that contains elements that themselves contain other objects:





Class objects: Another way to organize a DOM may be to provide several distinct class objects, each of them encapsulating unique functionality.


Creatable objects: Many objects are only present when needed, like colors, files, and more.



The DOM Extensions offers all of these mechanisms to access a host's object model. A host can decide freely which of these object structures to offer. A JavaScript-based host would, for example, offer all three combinations, while a plug-in that offers a restricted set of services might only offer class objects, and neither a root object (because there is no tree-like object structure) nor creatable objects (because there are no objects that are creatable).




The APE environment takes care of object lifetime issues and maintains the connection between host objects and the ActionScript object that they are wrapped into. The ActionScript programmer does not need to worry about issues like garbage collection, asynchronous state changes and the like.

Exceptions are a vital part of ActionScript. The APIs help with generating exceptions and forwarding them between the host and ActionScript. This way, a JavaScript based host could throw JavaScript exceptions into ActionScript, and vice versa.

Mush as the PatchPanel product today, there will be a set of wrapper libraries available that define a host's object model in ActionScript. These wrapper libraries can be used to speed up performance, and to provide safe type checking, code hints, help information and much more.



3. Flow Chart


The host loads a SWF file containing code that uses the HostObject APIs to access the host's DOM. 

Immediately after the SWF has been loaded, the SWF is not yet operational, because it has to execute its startup code (a.k.a frame #1) first. 
This gives the host time to register one or more DOM extensions, and to wait for the SWF to initialize. This wait is necessary if the host wishes to access the objects inside the SWF itself, since most of these objects will be created during the SWF's startup phase. If the host does not want to access the SWF's objects, it does not need to wait either.

The startup code inside the SWF already has full access to the host's object model, because the host registered its DOM extensions before allowing the startup code to execute.
For the interested: The SWF executes its startup code by sending out timer events.





4. Flash events


An ActionScript program often relies on Flash events. A typical Flash event is the click of a button. The ActionScript program can forward these events to the host, who in turn can choose to process these events. This makes it possible for a host environment to e.g. process Flash dialog events.

A Flash event is an ActionScript Event object, so it can be passed on, or created, just like any other ActionScript object. If a host application wants to process Flash events, it registers a function thatreceives these handlers. 
On the ActionScript side, there is a static HostObject.eventListener() method that can be registered as the event processing function. That method directs the event to the host application.

The host, on the other hand, can, of course, create Flash Event objects, and send them off to ActionScript to process. Thus, a host environment can e.g. choose to generate a Button Click event and send it off to a Flash dialog.

Develop Acrobat Plug-ins

Plug-ins
Plug-ins are dynamically-linked extensions to Acrobat or Adobe Reader. They can hook in to the user interface in a number of ways and can register to be called when a variety of events occur in the application.
A plug-in is written in ANSI C/C++ and uses the Acrobat public APIs. It can add functionality to Acrobat Pro Extended, Acrobat Professional, Acrobat Standard, or Adobe Reader. A plug-in program file goes into a Plug_ins folder or directory and is initialized during Acrobat or Adobe Reader startup.
There are three types of plug-ins:
  • Regular Acrobat plug-ins—These plug-ins run on Acrobat Professional and Acrobat Standard. Plug-ins for Acrobat Professional can use any of the Acrobat SDK APIs. Plug-ins for Acrobat Standard do not have access to some APIs.
  • Adobe Reader-enabled plug-ins—These plug-ins use a restricted set of APIs. Adobe Reader-enabled plug-ins are developed with permission from Adobe and require special processing to load under Adobe Reader. Plug-ins for Adobe Reader can use additional APIs if the PDF document has additional usage rights.
  • Certified plug-ins—These plug-ins have undergone extensive testing to ensure that they do not compromise the integrity of Acrobat's security model. A checkbox in the Acrobat and Adobe Reader user interface can be used to ensure that only certified plug-ins are loaded. Certified plug-ins can be provided only by Adobe.
On Windows, plug-ins are DLLs. However, plug-in names must end in .API, not .DLL. On Mac OS, plug-ins are code fragments, whereas on UNIX, plug-ins are shared libraries.


How to develop plugin:

When developing plugins using AFC Library the user has to derive his own plug in application class from the AFC core class AfcPIApp. And subsequently he/she has to override the member functionsSetPluginName , PluginInitialize , PluginImportReplaceAndRegister , PluginExportHFTs and PluginUnload. 


The SetPluginName function needs to be overridden by the user and should be implemented thus, so that the  function returns a pointer to a character string which is a unique name associated with the plug-in.

The PluginInitialize function is called by the Acrobat viewer during initialization to allow a plug-in to do any sort of initialization it requires, such as adding user interface. If the function returns false, thePluginUnload member function is called.

The PluginUnload function is called by the Acrobat viewer when the plug-in unloads to allow it to perform any sort of cleanup needed. Use this member function to release any system resources you may have allocated.
The PluginExportHFTs member function is called by the Acrobat viewer during initialization to allow a plug-in to export one or more HFTs to other plug-ins. Inside this member function the user should not do anything other than export HFTs. Plug-ins should not change the user interface at this time, do that in the PluginInitialize member function.

The PluginImportReplaceAndRegister member function is called by the viewer during the initialization to allow a plug-in to import HFT to another plug-in or replace an HFT method. This is the only place that a plug-in may replace a HFT method. Plug-ins should not change the user interface at this time, do that in the PluginInitialize member function.

// MyApp construction
MyApp ::MyApp ()
{
      // add construction code here,
      // Place all significant initialization in PluginInitialize 
}

// The one and only MyApp object
MyApp thePIApp;

// MyApp registering unique name
char* MyApp ::SetPluginName()
{
      char* m_szName;
      ......................
      ......................
      return m_szName;
}
// MyApp initialization
bool MyApp ::PluginInitialize()
{
       // intialization code goes here
          .......................
          .......................
          .......................
               return true;
          .......................
          .......................
          .......................
               return false;
}
// Import HFT to another plug-in or replace an HFT method.
bool MyApp ::PluginImportReplaceAndRegister()
{
          .......................
          .......................
          .......................
               return true;
          .......................
          .......................
          .......................
              return false;
}
// Export one or more HFTs to other plug-ins
bool MyApp ::PluginExportHFTs()
{
          .......................
          .......................
          .......................
              return true;
          .......................
          .......................
          .......................
             return false;
}
// MyApp,plug-in unloads
bool MyApp ::PluginUnload()
{
          .......................
          .......................
          .......................
              return true;
          .......................
          .......................
          .......................
              return false;
}

// MyApp destructor
MyApp ::~MyApp ()
{
      // add destruction code here,
      // Place all significant resource clean ups
}