Object ID externalization

Hello,
I might missed it but I did not find any support for Object ID
externalization in JDO specs.
I believe it is a much needed feature to be able to externalize Object
ID to lets say char array and being able to re-create Object ID from its
external form.
One simple example - passing Object ID as parameter to HTTP URL - you
need to externalize it first to produce URL and inside servlet you would
need to recreate the Object ID from its external form
Alex Roytman
Peace Technology, Inc.
301-206-9696 ext. 103

Hi Alex,
We are looking at a few methods that will help this situation, and will
probably adopt them in the next version of the specification.
The user-visible one is in PersistenceManager:
Object newObjectIdInstance(Class pcClass, String stringifiedObjectId).
The stringifiedObjectId is the result of toString on an object id:
stringifiedObjectId =
PersistenceManager.getObjectId(pcObject).toString().
Does this work for you?
Craig
"Roytman, Alex" wrote:
>
Hello,
I might missed it but I did not find any support for Object ID
externalization in JDO specs.
I believe it is a much needed feature to be able to externalize Object
ID to lets say char array and being able to re-create Object ID from its
external form.
One simple example - passing Object ID as parameter to HTTP URL - you
need to externalize it first to produce URL and inside servlet you would
need to recreate the Object ID from its external form
Alex Roytman
Peace Technology, Inc.
301-206-9696 ext. 103--
Craig Russell 650 786-7819
Architect mailto:[email protected]
Sun Microsystems, Inc. http://access1.sun.com/jdo

Similar Messages

  • RE: Object ID externalization

    Oh, sorry I missed it
    -----Original Message-----
    From: David Ezzio [mailto:[email protected]]
    Sent: Monday, August 13, 2001 9:25 PM
    To: [email protected]
    Cc: JDO-ListServ
    Subject: Re: Object ID externalization
    Alex,
    I think the new method Craig proposed
    PersistenceManager.newObjectIdInstance(...) is the API that you want to
    go from stringifiedObjectId to an ObjectId. It is possible however that
    we may have to post and pre process the stringifiedObjectId to make it
    happy with various protocols that we might want to pass it through.
    David

    Alex,
    I think the new method Craig proposed
    PersistenceManager.newObjectIdInstance(...) is the API that you want to
    go from stringifiedObjectId to an ObjectId. It is possible however that
    we may have to post and pre process the stringifiedObjectId to make it
    happy with various protocols that we might want to pass it through.
    David

  • Stupid NPE, passing over RMI, it is externalizable.

    Hi,
    I have an object (ObjectA) which holds a 2 element array of objects (ObjectB). Both objects are externalizable and have the read/writeExternal methods implemented. However when the server side receives the object the array of objects (ObjectB) contains all null values. Anyone any ideas?
    Thanks

    The null pointer exception occurs when I try to access a string in ObjectB. Its actually a 4 element array also. (Dont ask!).
    Code:
            //This is in the writeExternal
            if (objectBInstance!= null && objectBInstance.length > 0) {
                  oo.writeInt(objectBInstance.length);
                  oo.writeInt(objectBInstance[0].length);
                  oo.writeInt(objectBInstance[0][0].length);
                  oo.writeInt(objectBInstance[0][0][0].length);
                  for (int i = 0; i < objectBInstance.length; i++) {
                       for (int j = 0; j < objectBInstance.length; j++) {
                        for (int k = 0; k < objectBInstance[i][j].length; k++) {
                             for (int l = 0; l < objectBInstance[i][j][k].length; l++) {
                                  oo.writeObject(objectBInstance[i][j][k][l]);
         } else {
              oo.writeInt(0);
    //This is in the readExternal
    length = oi.readInt();
         if (length > 0) {
         int length2 = oi.readInt();
    int length3 = oi.readInt();
    int length4 = oi.readInt();
              objectBInstance= new ObjectB[length][length2][length3][length4];
              for (int i = 0; i < length; i++) {
                   for (int j = 0; j < length2; j++) {
                        for (int k = 0; k < length3; k++) {
                             for (int l = 0; l < length4; l++) {
                                  objectBInstance[i][j][k][l] = new ObjectB();
                                  objectBInstance[i][j][k][l] = (ObjectB)oi.readObject();
    Messy i know!
    The read/writeExternal in the objects used in ObjectB are ok too.

  • Why JMS if we can use JAVA classes for the same

    if we can communicate using the java classes which are protable and platform independent why do we have to use JMS for that. what is so specific about it and what is the benefit that makes it outstanding

    James/Steve,
    I feel that some of your points are misleading. The original authors point was a comparison against JMS and other means of achieving similar functionality with Java. Regarding your combined points:
    2) Scalability is something that can be achieved regardless of whether JMS is used. Clustering has nothing to do with JMS, each vendors clustering implementation is entirely proprietary.
    4) Aside from the inclusion of JNDI the JMS specification offers nothing for management. You only need to look through this forum at the amount of times a question like �how do I make a topic programmatically?� has been asked. All good JMS vendors offer management API�s and tools but all are vendor specific implementations.
    10) There is no JMS standard for load balancing. The generic round robin features of a JMS queue falls a long way short of true �load balancing�. Any vendor (ourselves included) that offers load balancing does so in an entirely proprietary manner.
    11) Again�JMS provides no standards for clustering of running one or more server. This is entirely down to implementation and functionality is vendor specific.
    12) Dead Message/Letter Queues are not defined in JMS
    14) What does serialization have to do with the original point? How one chooses to serialize their content ( XML, Object Serialization, Externalizable etc..) is equally applicable to both bespoke Java coding and JMS implementations.
    To birs1982:
    JMS is merely a collection of interfaces that define how one might read and write to a topic or queue. Vendors (both open source and commercial) recognize that these interfaces alone are not enough to offer an entire middleware messaging solution and complete the offering with sophisticated management, resilience, clustering, security and other value added features. These value added features require considerable effort to get right as do things like scalability and performance.
    Given JMS like messaging is almost commodity now (just look at the amount of JMS vendors that have leaped into the ESB space) and a common (perhaps essential) infrastructure component why produce it yourself? Surely your time is better spent serving your clients and business lines rather that writing what amounts to plumbing. All the hard work has been done and the price for this hard work (depending on your requirements) is anything from free to many thousands of pounds.
    Regards,
    Paul Brant
    my-Channels - Technologies working together
    http://www.my-channels.com/

  • How ObjectInputStream.readObject() works??

    Below is Test.java, some codes on simple serialization operations (copied from a book.) A "Blip1" object is created, serialized to a file, then deserialized back from the file. Everything works fine!!
    My question is, why does the last line work, "b1 = (Blip1)in.readObject();" ?
    I mean, ObjectInputStream is part of [package java.io], how can we create a "Blip1" object of [package anypackage] while we are inside [package java.io]?? Am I missing something fundamental?
    I thought this ObjectInputStream.readObject() is based on Reflection, that is, ObjectInputStream.readObject() created the "Blip1" object based on the class name. So I wrote Creator.java (see below) and the result was an IllegalAccessException --- we cannot create a "Blip1" object while we are inside another package. This shows that ObjectInputStream.readObject() is not really based on Reflection(??)
    How does ObjectInputStream.readObject() work??
    //Test.java
    package anypackage;
    class Blip1 implements Externalizable {
      public Blip1() {System.out.println("Blip1 created");}
      public void writeExternal(ObjectOutput out) throws IOException {}
      public void readExternal(ObjectInput in)
        throws IOException, ClassNotFoundException {}
    public class Test {
      public static void main(String[] args)
      throws IOException, ClassNotFoundException {
        System.out.println("Constructing objects:");
        Blip1 b1 = new Blip1();
        ObjectOutputStream o = new ObjectOutputStream(
          new FileOutputStream("Blips.out"));
        System.out.println("Saving objects:");
        o.writeObject(b1);
        o.close();
        // Now get them back:
        ObjectInputStream in =
          new ObjectInputStream(
            new FileInputStream("Blips.out"));
        System.out.println("Recovering b1:");
        b1 = (Blip1)in.readObject();
    //Creator.java
    package anyotherpackage;
    import java.util.*;
    public class Creator{
      Object o;
      public Creator(){
        try{
          Class c = Class.forName("anypackage.Blip1");
          Object o = c.newInstance();
        } catch (Exception e){
          System.out.println(e);
      public static void main(String[] args){
        Creator c = new Creator();
    }

    As far as i understand the ObjectInputStream.readObject() create object by recursively building the memory owned by the object, obviously object Ctor is not called (otherwise serializeable classes were forced to have empty Ctor).
    It goes like this -
    1)when object implements Serializable interface its stream hold description of the the object memory (for each datamember we will have something like offset,datamember type, and streamed datamember), ObjectInputStream.readObject build the datamembers recursively (recursion is stopped when we have primitive type datamember)
    2)when object implements Externalizable interface the programmer is responsible to stream object's datamembers to the ObjectOutput and to read them from the ObjectInput, ObjectInputStream is responsible to create an empty object for you
    anyway no Ctors are involved

  • Does CohQL backup support POF?

    I'm trying to use the CohQL command line application to backup my test data set and I'm getting the following (with the actual package and class name changed):
    java.io.NotSerializableException: mypackage.MyClass$Key
    java.lang.RuntimeException: Error in BACKUP
    The class I'm caching instances of, including the inner class used as a key, all implement PortableObject, but not Serializable. I've changed the query.sh script to include the same tangosol.coherence.cacheconfig, tangosol.pof.config, etc. parameters than I'm using in the other processes that are populating and reading from the cache, and I can query the cache using CohQL w/o any problems. Should this work or does CohQL just not support backing up POF objects?
    Thanks.

    It's because backup option doesn't support POF objects.
    I've did a quick lookup in the import references within CohQL classes, from a first look it seems like backup is supported only for cache objects, implementing Externalizable or ExternalizableLite interface.
    Yet another bug/unfinished feature in 3.6 version, it's especially annoying since Coherence docs are encouraging use of POF literally on every page.
    Taking into account this ant other bugs within key & new functionality sets I assume the quality of code & testing has dropped significantly in release 3.6.
    And I have really bad guesses on reasons of that. :(

  • Writing Objects to file using Externalizable

    Hi,
    I'm trying to write an object to file. My sample code is:
    public class Junk implements Externalizable{
    private static java.util.Random generator = new java.util.Random();
    private int answer;
    private double[] numbers;
    private String thought;
    public Junk(String thought) {
    this.thought = thought;
    answer = 42;
    numbers = new double[3+ generator.nextInt(4)];
    for (int i=0; i<numbers.length; i++) {
    numbers[i] = generator.nextDouble();
    public void writeExternal(ObjectOutput stream) throws java.io.IOException {
    stream.writeInt(answer);
    stream.writeBytes(thought);
    for(int i=0; i< numbers.length; i++) {
    stream.writeDouble(numbers);
    public void readExternal(ObjectInput stream) throws java.io.IOException {
    answer = stream.readInt();
    String thought = stream.readUTF();
    and the class with main() is:
    package MyTest;
    import java.io.*;
    public class SerializeObjects {
    public SerializeObjects() {
    public static void main(String args[]) {
    Junk obj1 = new Junk("A green twig is easily bent.");
    Junk obj2 = new Junk("A little knowledge is a dangerous thing.");
    Junk obj3 = new Junk("Flies light on lean horses.");
    ObjectOutputStream oOut = null;
    FileOutputStream fOut = null;
    try {
    fOut = new FileOutputStream("E:\\FileTest\\test.bin");
    oOut = new ObjectOutputStream(fOut);
    obj1.writeExternal(oOut);
    //obj2.writeExternal(oOut);
    } catch (IOException e) {
    e.printStackTrace(System.err);
    System.exit(1);
    try {
    oOut.flush();
    oOut.close();
    fOut.close();
    } catch(IOException e) {
    e.printStackTrace(System.err);
    System.exit(1);
    The output I get in test.bin contains some junk ascii codes. The only item that is written correctly in the file is the string.
    Is there anyway I can write correct data into a file?
    My output needs to be a readable text format file.
    Can anyone help please?

    obj1.writeExternal(oOut);This should be
    oOut.writeObject(obj1);However,
    The output I get in test.bin contains some junk ascii
    codes. The only item that is written correctly in the
    file is the string.If you don't want 'junk' don't use Externalizable and ObjectOutputStream at all, just use PrintStream/PrintWriter.println().

  • Externalizable and compatibility with existing serialized objects

    I have an object in a db in a serialized state as a result of writeExternal. I want to change the class's writeExternal and readExternal such that a String that should have been serialized is now serialized.
    What is the best practice for supporting existing serialized versions of the class being read by my amended version?
    Should I add to the end of readExternal and writeExternal and catch an IOException in readExternal? Will readExternal even through an IOException if my stream is exhausted? And I guess IOException could be caught for other reasons that stream exhaustion so I should not rely on it being thrown for that reason alone?
    writeExternal(ObjectOutput out)
    out.writeObject(m_1);
    out.writeObject(m_2);
    out.writeObject(m_theNewOne);
    readExternla(ObjectInput in)
    m_1 = (String)in.readObject();
    m_2 = (String)in.readObject();
    try
    m_theNewOne = (String)in.readObject();
    catch (IOException e)
    m_theNewOne = "default value";
    Thanks.

    If your readExternal method tries to data that isn't there it will get a -1 from primitive reads, EOFException from DataInputStream.readXXX methods, or from readObject() calls it will get an OptionalDataException with the eof field set to true.
    See http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/input.html#6014.

  • Read data from Vector object serialized in a file issue!!

    Hi all,
    I have two classes :CBase and CHelper class in a package and serializing some information in a file and then reading it. I am facing some problem while reading the data
    which was stored using vector of objects. Below is the detailed problem:::::
    ////////////CHELPER
    public class CHelper implements Externalizable, Cloneable {
    public string szname;
    //..other functions writeexternal read external
    ////////////CBASE
    public class CBase
    implements Externalizable, Cloneable {
    protected boolean bRead;
    protected boolean bWrite;
    protected Vector vData;
    public void addInstance(CHelper obj) {
    vData.addElement(obj);
    //..other functions writeexternal read external
    I am Serializing all the CBase information in a file and trying to read the contents from this serialized file::::
    CBase base = new CBase();
    CHelper obj = new CHelper();
    obj.setName("HELPER");
    base.addInstance(obj); // ADDING THE OBJECT DATA INTO THE VECTOR
    base.bRead = true;
    base.bWrite = true;
    // Writing to the file
    FileOutputStream fs = new FileOutputStream("d:\\temp\\Base.txt");
    ObjectOutputStream os = new ObjectOutputStream(fs);
    os.writeObject(base);
    os.close();
    //reading from the file
    FileInputStream fi = new FileInputStream("d:\\temp\\Base.txt");
    ObjectInputStream oi = new ObjectInputStream(fi);
    CBase read = (CBase) oi.readObject();
    PRINTING THE OUTPUT
    System.out.println("Vector = " + read.vData.firstElement().toString());
    System.out.println("Write = " + read.bRead);
    System.out.println("Read = " + read.bWrite);
    The output is something like:
    Vector = com.sp.CHelper@14b7453 // WHAT IS THIS ?? GARBAGE ?? NOT ABLE TO ANALYSE :(
    Write = true;
    Read = true;************
    MY PROBLEM:
    i.e How to get the information stored in the Vector ? I am getting something "com.sp.CHelper@14b7453 " whereas the expected output should be Vector = HELPER. I am
    writing and reading the vector as follows:
    // CHELPER
    public void writeExternal(ObjectOutput out) throws IOException {
    out.writeUTF(szName.toString());
    public void readExternal(ObjectInput in) throws IOException,
    ClassNotFoundException {
    setName(in.readUTF());
    Externalize in CBase Classs
    out.writeInt(getInstanceCount()); // getting number of objects in the vector
    for (int index = 0; index < getInstanceCount(); index++) {
    out.writeObject((CHelper)vData.get(index));
    out.writeBoolean(bWrite);
    out.writeBoolean(bRead);
    And reading like this::
    int iNumberofInstances; // number of instances
    iNumberofInstances = in.readInt();
    vData.clear();
    // Get the CHelper object and add it into the CFeatureBase vector
    for (int i = 0; i < iNumberofInstances; i++) {
    CHelper objbase = (CHelper)in.readObject();
    vData.add(objbase);
    this.bWrite = in.readBoolean();
    this.bRead = in.readBoolean();
    I suppose that i am correctly WRITING AND READING the data. B/w what can be the problem. All suggestions are welcome/
    Thanks,
    Rohit

    Vector = com.sp.CHelper@14b7453 // WHAT IS THIS ??
    GARBAGE ?? NOT ABLE TO ANALYSE :(
    Write = true;
    Read = true;************
    MY PROBLEM:
    i.e How to get the information stored in the Vector
    ? I am getting something "com.sp.CHelper@14b7453 "
    whereas the expected output should be Vector =
    HELPER.This is perfectly normal behaviour if your CHelper class doesn't override the toString() method. The default toString() method in Object just prints the name of the class and a hex representation of the object's hash code.
    Add a toString() method to CHelper that returns szname and you should see what you are expecting.

  • User-Defined Data Type (Data Transfer Objects) is null

    hi
    i try to access a nested complex datatype over blazeds. i always see that the second level of the  complex datatye is NULL but the other data's like String are ok.
    here an example:
    as you can see TT1 has a member TT2, and a String
    TT2 has a member TT3 and a string
    and TT3 has just a string.
    in the ActionScript the TT2 referenz in TT1 is always NULL.
    Java Code
    Java code:
    package clientreportingserver;
    public class TT1 {
        public String getT1s() {
            return t1s;
        public void setT1s(String t1s) {
            this.t1s = t1s;
        String t1s;
        public TT2 getTt2() {
             return tt2;
        public void setTt2(TT2 tt2) {
             this.tt2 = tt2;
        TT2 tt2;
    =================================================
    package clientreportingserver;
    public class TT2 {
        public String getT2s() {
            return t2s;
        public void setT2s(String t2s) {
            this.t2s = t2s;
        String t2s;
        public TT3 getTt3() {
             return tt3;
        public void setTt3(TT3 tt3) {
             this.tt3 = tt3;
        TT3 tt3;
    =================================================
    package clientreportingserver;
    public class TT3 {
         public String getT3s() {
            return t3s;
        public void setT3s(String t3s) {
            this.t3s = t3s;
        String  t3s;
    ActionScript DataType
    package clientreporting.model
    import mx.collections.ArrayCollection;
    [RemoteClass(alias="clientreportingserver.TT1")]
    [Bindable]
    public class TT1
        public var t1s:String;
        public var t2:TT2
    ====================================================================
    package clientreporting.model
    import mx.collections.ArrayCollection;
    [RemoteClass(alias="clientreportingserver.TT2")]
    [Bindable]
    public class TT2
        public var t2s:String;
        public var t2:TT3
    ===================================================================
    package clientreporting.model
    import mx.collections.ArrayCollection;
    [RemoteClass(alias="clientreportingapi.TT3")]
    [Bindable]
    public class TT3
        public var t3s:String;
    here the output from blazeds. for me it looks perfect, all data are transmitted
    BlazeDs output
    [BlazeDS]Deserializing AMF/HTTP request
    Version: 3
      (Message #0 targetURI=null, responseURI=/5)
        (Array #0)
          [0] = (Typed Object #0 'flex.messaging.messages.RemotingMessage')
            source = null
            operation = "getTT"
            destination = "exposedServiceWrapper"
            clientId = "E57066B1-170E-503A-D4EC-004166E95FC3"
            body = (Array #1)
            timeToLive = 0
            headers = (Object #2)
              DSEndpoint = "channel-amf"
              DSId = "E570490A-C218-4A29-4229-8CD6F29222FC"
            timestamp = 0
            messageId = "5FDB47AD-9066-DD95-4CD4-0CE0D3F6C337"
    [BlazeDS]Adapter 'java-object' called 'null.getTT(java.util.Arrays$ArrayList (Collection size:0)
    [BlazeDS]Result: 'clientreportingserver.TT1
      t1s = TT 1 String
      tt2 = clientreportingserver.TT2
        t2s = TT 2 String
        tt3 = clientreportingserver.TT3
          t3s = TT 3 String
    [BlazeDS]Serializing AMF/HTTP response
    Version: 3
      (Message #0 targetURI=/5/onResult, responseURI=)
        (Externalizable Object #0 'DSK')
          (Typed Object #1 'clientreportingserver.TT1')
            t1s = "TT 1 String"
            tt2 = (Typed Object #2 'clientreportingserver.TT2')
              t2s = "TT 2 String"
              tt3 = (Typed Object #3 'clientreportingserver.TT3')
                t3s = "TT 3 String"
    1.262936445958E12
    (Byte Array #4, Length 16)
    (Byte Array #5, Length 16)
    (Byte Array #6, Length 16)
    the last Alert (accessing t2) got always a null pointer, the fist Alert works fine and print out the string i expected to see
    call in ActionScript
        public function loadTT():void {
           _policyService.getTT(loadTTHandle);
        private function loadTTHandle(content:TT1):void {
           Alert.show("" + content.t1s);
           Alert.show("" + content.t2.t2s);
    is it possible to access a nested complex type? i only could find simple examples.
    thanks for your help joe

    I found the problem
    in the flashlog.txt i found :ReferenceError: Error #1056: Cannot create property AFoo on [...]
    this let me to this blog http://blog.comtaste.com/java/  ==>
    Automating  ActionScript 3 classes generation from Java Beans in a LiveCycle Data Services context
    it was a naming problem.

  • Explicity mapping between ActionScript and Java objects for the BlazeDS Messaging Service

    The BlazeDS documentation shows how to explicitly map between ActionScript and Java objects. For example, this works fine for RPC services, e.g.
    import flash.utils.IExternalizable;
    import flash.utils.IDataInput;
    import flash.utils.IDataOutput;
    [Bindable]
    [RemoteClass(alias="javaclass.User")]
    public class User implements IExternalizable {
            public var id : String;
            public var secret : String;
            public function User() {
            public function readExternal(input : IDataInput) : void {
                    id = input.readObject() as String;
            public function writeExternal(output : IDataOutput) : void {
                    output.writeObject(id);
    and
    import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    public class User implements Externalizable {
        protected String id;
        protected String secret;
        public String getId() {
            return id;
        public void setId(String id) {
            this.id = id;
        public String getSecret() {
            return secret;
        public void setSecret(String secret) {
            this.secret = secret;
        public void readExternal(ObjectInput in) throws IOException,
                    ClassNotFoundException {
            id = (String) in.readObject();
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject(id);
    If I called an RPC service that returns a User, the secret is not sent over the wire.  Is it also possible to do this for the messaging service? That is, if I create a custom messaging adapter and use the function below, can I also prevent secret from being sent?
    MessageBroker messageBroker = MessageBroker.getMessageBroker(null);
    AsyncMessage message = new AsyncMessage();
    message.setDestination("MyMessagingService");
    message.setClientId(UUIDUtils.createUUID());
    message.setMessageId(UUIDUtils.createUUID());
    User user = new User();
    user.setId("id");
    user.setSecret("secret");
    message.setBody(user);
    messageBroker.routeMessageToService(message, null);

    Hi Martin. The way that AMF serialization/deserialization works for BlazeDS is the same regardless of which service is being used, so yes that code will work for messaging as well. On the server, the serialization/deserialization of messages happens at the endpoint. For an incoming message for example, the endpoint deserializes the message and then hands it off to the MessageBroker which decides which service/destination to deliver the message to.
    That was a good question. Thanks for asking it. Lots of people are used to doing custom serialization/deserialization with the RPC services (RemoteObject/RemotingService) but I'm not sure everyone realizes they can do this for messaging as well.
    -Alex

  • How to Convert Externalizable objec to Serializable at Run Time

    Urgent Help needed ...
    Original Problem
    We are using Externalizable object through the system .We keep track of versioning with field in each object ...
    This version is common software version...
    We change that version every two or three week ...
    suppose for
    My software Version is 2
    and suppose if someone add a new field to any object we put a checking in readExternal to not read that field is the version is less than 2
    Now the problem is say
    1)We make a version 2 on June 10
    2)Some one save a object on June 11
    3)Some one add a new field in any object and put the checking of Version 2
    4)Now object saved in step 2 cannot be read once step 3 is performed...
    How do we solve this issue ?
    We do not intend to add the class Version in each class at this stage. ...
    Issue 2
    Other issue related to issue 1 itself
    We plan to convern the object to xml using some technology of Xstream
    Now issue 1 can be solved atlease if my all the object were of type Serializable and NOT EXTERNALIZABLE
    So my Second Question is is there a way to convert a Externalizable object to Serialiable object just for my purpose when i m converting to xml and vice versa .....
    Basicallly I want a way to remove that EXTERNALIZABLE Interface from class at run time WITHOUT CHANGING ANY CLASS SOURCE CODE ...../
    Guy Your help is very appreiciated to solve this two issue
    Message was edited by:
    palanmahesh

    It seem i have not properly explained to you guys my
    problem
    I cannot change the code of existing object which are
    Externalizable..
    Nor can i solve the versioning issue That block of
    source code i cannot touch
    all i want is somehow convert the object so that they
    are not instance of Externalizable Well it seems pretty hopeless then doesn't it.
    My advice? Give up. You seem pretty lost and when people respond by basically saying they can't solve the problem in any reasonable way then it's pretty much a lost cause.
    Good luck with your hopeless task. I see nothing but upset in your future.

  • Export Aperture library objects to Finder folders

    Inspired by the posted message by user http://discussions.apple.com/profile.jspa?userID=616539 I wrote a script that will do the following:
    1. Sync Folders/SubFolders/Albums/Projects..etc hierarchy tree from Aperture to a Finder folders tree
    2. At run-time the script will creates/append to a log file under (home directory)\Library\Logs\AppleScriptExportApertureLibrary.log
    3. Exports all projects images versions with embedded metadata
    4. Create a file system "hard links" for each photo in the respective Albums pointing to the project folder location in order to preserve space.
    5. Compare modification date on the image files and modification date within Aperture and export only modified images in order to save time for a full sync/export.
    6. In interactive mode you can select Export Folder location, Aperture Library location and Projects List (project list will contain project name and internal aperture project id).
    7. In non-interactive (from command line) mode there are two arguments:
    7a. "quiet" - exports all projects
    7b. "quiet" "Project Information" - export only certain projects. the project information can be found in the log file.
    8. Remove any images or folders from Finder export directory that do not exist in Aperture database any more.
    Hopefully this would help anyone who is looking to export from Aperture on a regular basis. I am not sure how it will handle large amount of photos. I tested it with 3k+ photos.
    Please note that you use this script at your own risk.
    Here is the script code:
    global theFoldersTree_G
    global theLibraryPath_G
    global theProcessedProjects_G
    global theSelectedProjects_G
    global theAllAlbums_G
    global theScriptName_G
    global Sqlite_G
    global ApertureLibrary_G
    global numExports_G
    on run argv
    set Sqlite_G to "/usr/bin/sqlite3"
    set ApertureLibraryPath to POSIX path of (path to home folder) & "Pictures/"
    set ApertureLibrary_G to ApertureLibraryPath & "Aperture Library.aplibrary/Aperture.aplib/Library.apdb"
    set exportFolder to POSIX path of (path to home folder) & "Pictures/Aperture Exports/"
    set theScriptName_G to "ExportApertureLibrary"
    set theSelectedProjects_G to "ALL PROJECTS"
    set theFoldersTree_G to {}
    set theProcessedProjects_G to {}
    set theAllAlbums_G to {}
    set numExports_G to 0
    logEvent("Started")
    set theArgv1 to {}
    set theArgv2 to {}
    if (count of argv) ≥ 1 then
    set theArgv1 to item 1 of argv
    end if
    if (count of argv) = 2 then
    set theArgv2 to item 2 of argv
    end if
    logEvent("Passed ARGV 1: " & theArgv1)
    logEvent("Passed ARGV 2: " & theArgv2)
    if theArgv1 is not equal to "quiet" then
    set theFile to (choose file with prompt "Please choose the Aperture Library file" default location POSIX file ApertureLibraryPath) as string
    set ApertureLibrary_G to POSIX path of theFile & "Aperture.aplib/Library.apdb"
    set exportFolder to POSIX path of (choose folder with prompt "Please choose the export folder" default location POSIX file exportFolder) as string
    end if
    logEvent("ApertureLibrary_G path is set to: " & ApertureLibrary_G)
    logEvent("exportFolder path is set to: " & exportFolder)
    try
    tell application "Aperture"
    logEvent("Getting list of project path information...") of me
    set SqlStatement to "
    select replace(A.ZLIBRARYRELATIVEPATH,'.approject',''),A.ZUUID
    from ZRKFOLDER AS A
    WHERE A.ZFOLDERTYPE=2
    ORDER BY A.ZNAME"
    set SQLProjectUUIDPath to DB_execute(SqlStatement) of me
    set theProjectsOptions to SQLProjectUUIDPath as list
    set end of theProjectsOptions to "ALL PROJECTS"
    logEvent("Projects list: " & theProjectsOptions as string) of me
    if theArgv1 is not equal to "quiet" then
    set theSelectedProjects_G to choose from list SQLProjectUUIDPath with prompt "Please choose a project(s):"
    end if
    if theArgv2 is not equal to {} then
    set theSelectedProjects_G to theArgv2
    end if
    logEvent("The selected projects : " & theSelectedProjects_G as string) of me
    logEvent("Getting list of libraries...") of me
    set theLibraryList to every library
    logEvent("Found " & (count of theLibraryList) & " libraries") of me
    repeat with theLibrary in theLibraryList
    set theLibraryName to name of theLibrary
    logEvent("Processing library: " & theLibraryName) of me
    set LibraryFolders to {}
    set theProcessedProjects_G to {}
    tell application "Finder"
    if not (exists (POSIX file (exportFolder & theLibraryName) of me)) then
    logEvent("creating new folder " & theLibraryName & " at " & exportFolder) of me
    make new folder at (POSIX file exportFolder of me) with properties {name:theLibraryName}
    end if
    end tell
    set theLibraryPath_G to exportFolder & theLibraryName & "/"
    logEvent("Getting list of folders...") of me
    set theFolderList to every folder of library id (id of theLibrary)
    logEvent("Found " & (count of theFolderList) & " folders") of me
    set theRootFolderList to {}
    if theFolderList is not equal to {} then
    processFoldersTree(0, theFolderList) of me
    repeat with theFolder in theFolderList
    if (id of theFolder) is not in theFoldersTree_G as string then
    logEvent("Found root folder : " & (name of theFolder) as string) of me
    set end of theRootFolderList to theFolder
    set end of LibraryFolders to (name of theFolder)
    end if
    end repeat
    end if
    if theRootFolderList is not equal to {} then
    processFolders(theRootFolderList, theLibraryPath_G, "projects") of me
    processFolders(theRootFolderList, theLibraryPath_G, "albums") of me
    else
    set theProjectList to every project of library id (id of theLibrary)
    set end of LibraryFolders to processProjects(theProjectList, theLibraryPath_G, "projects") of me as list
    processProjects(theProjectList, theLibraryPath_G, "albums") of me
    end if
    logEvent("Getting list of projects...") of me
    set theProjectList to every project of library id (id of theLibrary)
    logEvent("Found " & (count of theProjectList) & " projects") of me
    logEvent("Getting list of albums...") of me
    set theAlbumList to every album of library id (id of theLibrary)
    logEvent("Found " & (count of theAlbumList) & " albums") of me
    set theRootProjectList to {}
    if theProjectList is not equal to {} then
    repeat with theProject in theProjectList
    if (id of theProject) is not in theProcessedProjects_G as string then
    logEvent("Found root project : " & (name of theProject) as string) of me
    set end of theRootProjectList to theProject
    set end of LibraryFolders to (name of theProject)
    end if
    end repeat
    end if
    set theRootAlbumList to {}
    if theAlbumList is not equal to {} then
    processAlbumsTree(theProjectList, theFolderList) of me
    set theRootAlbumList to {}
    repeat with theAlbum in theAlbumList
    if (id of theAlbum) is not in theAllAlbums_G as string then
    logEvent("Found root album : " & (name of theAlbum) as string) of me
    set end of theRootAlbumList to theAlbum
    set end of LibraryFolders to (name of theAlbum)
    end if
    end repeat
    end if
    if theRootProjectList is equal to {} then
    processAlbums(theRootAlbumList, theLibraryPath_G, "albums") of me
    else
    processProjects(theRootProjectList, theLibraryPath_G, "projects") of me
    processProjects(theRootProjectList, theLibraryPath_G, "albums") of me
    if theRootAlbumList is not equal to {} then
    processAlbums(theRootAlbumList, theLibraryPath_G, "albums") of me
    end if
    end if
    cleanup(LibraryFolders, theLibraryPath_G, "all") of me
    end repeat
    logEvent("total exports : " & numExports_G) of me
    if theArgv1 is not equal to "quiet" then
    display dialog "Total image exports : " & numExports_G buttons {"OK"} with title "Aperture Library Export" with icon note
    end if
    end tell
    on error s number i partial result p from f to t
    set s to "Error: " & s
    logEvent(quoted form of (s))
    if theArgv1 is not equal to "quiet" then
    display dialog "ERROR : " & s buttons {"OK"} with title "Aperture Library Export" with icon note
    end if
    end try
    end run
    on cleanup(theObjects, thePath, theSelection)
    logEvent("Cleaning export folders...") of me
    logEvent("# Objects: " & (count of theObjects)) of me
    logEvent("Export Folder: " & (thePath as string))
    tell application "Finder"
    logEvent("Getting list of folders...") of me
    set theFolderList to every folder in folder (POSIX file thePath of me)
    logEvent("Found " & (count of theFolderList) & " folders") of me
    logEvent("Getting list of files...") of me
    set theFileList to every file in folder (POSIX file thePath of me)
    logEvent("Found " & (count of theFileList) & " files") of me
    repeat with theFolder in theFolderList
    set theFolderName to name of theFolder
    if theFolderName is not in theObjects as string then
    logEvent("Moving folder " & theFolder & " to trash...") of me
    move theFolder to trash
    end if
    end repeat
    if theSelection is not equal to "folder" then
    repeat with theFile in theFileList
    set theFileName to name of theFile
    if theFileName is not in theObjects as string then
    logEvent("Moving file " & theFile & " to trash...") of me
    move theFile to trash
    end if
    end repeat
    end if
    end tell
    logEvent("Cleaning completed...") of me
    end cleanup
    on logEvent(logMessage)
    set theLine to quoted form of (((current date) as string) ¬
    & " : " & logMessage)
    do shell script "echo " & theLine & ¬
    " >> ~/Library/Logs/AppleScript" & theScriptName_G & ".log"
    end logEvent
    on DB_lookupProjectPath(puuid)
    set SqlStatement to "
    select replace(rtrim(ZLIBRARYRELATIVEPATH,'.approject'),'/',':' )
    from ZRKFOLDER
    where
    ZUUID ='" & puuid & "'"
    set SqlRecords to DB_execute(SqlStatement)
    return DB_record(SqlRecords, 1, 1)
    end DB_lookupProjectPath
    on processFolders(theFoldersList, theFolderPath, processOrder)
    logEvent("processFolders... : " & theFolderPath) of me
    set arrayOfFolders to {}
    tell application "Aperture"
    set theCount to count of theFoldersList
    set theCounter to 1
    repeat with theFolder in theFoldersList
    set foldersOfFolder to {}
    set theFolderName to name of theFolder
    logEvent("Processing folder : " & theFolderName & " (" & theCounter & "/" & theCount & ")") of me
    set theCounter to theCounter + 1
    set end of arrayOfFolders to theFolderName
    tell application "Finder"
    if not (exists (POSIX file (theFolderPath & theFolderName) of me)) then
    logEvent("creating new folder " & theFolderName & " at " & theFolderPath) of me
    make new folder at (POSIX file theFolderPath of me) with properties {name:theFolderName}
    end if
    end tell
    logEvent("Getting list of album...") of me
    set theAlbumsListOfFolder to every album of folder id (id of theFolder)
    logEvent("Found " & (count of theAlbumsListOfFolder) & " albums") of me
    logEvent("Getting list of folder...") of me
    set theFolderListOfFolder to every folder of folder id (id of theFolder)
    logEvent("Found " & (count of theFolderListOfFolder) & " folders") of me
    logEvent("Getting list of project...") of me
    set theProjectsListOfFolder to every project of folder id (id of theFolder)
    logEvent("Found " & (count of theProjectsListOfFolder) & " projects") of me
    if theProjectsListOfFolder is not equal to {} then
    set end of foldersOfFolder to processProjects(theProjectsListOfFolder, (theFolderPath & theFolderName & "/"), processOrder) of me as list
    end if
    if theFolderListOfFolder is equal to {} then
    set end of foldersOfFolder to processAlbums(theAlbumsListOfFolder, (theFolderPath & theFolderName & "/"), processOrder) of me as list
    else
    if theAlbumsListOfFolder is not equal to {} then
    set end of foldersOfFolder to processAlbums(theAlbumsListOfFolder, (theFolderPath & theFolderName & "/"), processOrder) of me as list
    end if
    set end of foldersOfFolder to processFolders(theFolderListOfFolder, (theFolderPath & theFolderName & ":"), processOrder) of me as list
    end if
    cleanup(foldersOfFolder, (theFolderPath & theFolderName & "/"), "all") of me
    end repeat
    end tell
    logEvent("processFolders completed...") of me
    return arrayOfFolders
    end processFolders
    on processFoldersTree(theParent, theFoldersList)
    logEvent("processFoldersTree...") of me
    tell application "Aperture"
    repeat with theFolder in theFoldersList
    if theParent is not 0 then
    set end of theFoldersTree_G to (id of theFolder)
    end if
    set theFolderListOfFolder to every folder of folder id (id of theFolder)
    if theFolderListOfFolder is not equal to {} then
    processFoldersTree((id of theFolder), theFolderListOfFolder) of me
    end if
    end repeat
    end tell
    logEvent("processFoldersTree completed...") of me
    end processFoldersTree
    on processAlbumsTree(theProjectsList, theFoldersList)
    logEvent("processAlbumsTree...") of me
    set theAllAlbums_G to {}
    tell application "Aperture"
    repeat with theProject in theProjectsList
    repeat with theAlbum in (every album of project id (id of theProject))
    set end of theAllAlbums_G to (id of theAlbum)
    end repeat
    end repeat
    repeat with theProject in theProjectsList
    repeat with theAlbum in (every album of every subfolder of project id (id of theProject))
    set end of theAllAlbums_G to (id of theAlbum)
    end repeat
    end repeat
    repeat with theFolder in theFoldersList
    repeat with theAlbum in (every album of folder id (id of theFolder))
    set end of theAllAlbums_G to (id of theAlbum)
    end repeat
    end repeat
    end tell
    logEvent("processAlbumsTree completed...") of me
    end processAlbumsTree
    on DB_lookupImageInfo(puuid)
    set SqlStatement to "
    SELECT replace(A.ZLIBRARYRELATIVEPATH,'.approject',''),strftime('%m/%d/%Y %H:%M:%S',datetime(B.ZDATELASTSAVEDINDATABASE, 'unixepoch', '+31 years','localtime'))
    from ZRKFOLDER AS A,ZRKVERSION AS B
    where
    B.ZPROJECTUUID = A.ZUUID AND
    B.ZUUID ='" & puuid & "'"
    set SqlRecords to DB_execute(SqlStatement)
    return {theImagePath:DB_record(SqlRecords, 1, 1), theImageDate:DB_record(SqlRecords, 1, 2)}
    end DB_lookupImageInfo
    on processProjects(theProjectsList, theProjectPath, processOrder)
    logEvent("processProjects... : " & theProjectPath) of me
    logEvent("processOrder: " & processOrder) of me
    set arrayOfProjects to {}
    tell application "Aperture"
    set theCount to count of theProjectsList
    set theCounter to 1
    repeat with theProject in theProjectsList
    set ProjectFolders to {}
    set theProjectName to name of theProject
    set end of arrayOfProjects to theProjectName
    set theContinue to 0
    if "ALL PROJECTS" is not in theSelectedProjects_G as string then
    if (id of theProject) is not in theSelectedProjects_G as string then
    logEvent("Skipping project: " & theProjectName) of me
    set theContinue to 1
    end if
    end if
    if theContinue = 0 then
    -- set theProjectPath to theProjectPath & DB_lookupProjectPath(id of theProject) of me
    logEvent("Processing project : " & theProjectName & " (" & theCounter & "/" & theCount & ")") of me
    tell application "Finder"
    if not (exists (POSIX file (theProjectPath & theProjectName) of me)) then
    logEvent("creating new folder " & theProjectName & " at " & theProjectPath) of me
    make new folder at (POSIX file theProjectPath of me) with properties {name:theProjectName}
    end if
    end tell
    if processOrder is equal to "projects" then
    set end of theProcessedProjects_G to (id of theProject)
    logEvent("Getting list of images...") of me
    set theImageList to every image version of project id (id of theProject) as list
    logEvent("Found " & (count of theImageList) & " images") of me
    set end of ProjectFolders to processImages(theImageList, (theProjectPath & theProjectName & "/"), "project", "JPEG - Original Size") of me as list
    end if
    logEvent("Getting list of subfolders...") of me
    set theSubfolderList to every subfolder of project id (id of theProject)
    logEvent("Found " & (count of theSubfolderList) & " subfolders") of me
    logEvent("Getting list of album...") of me
    set theAlbumList to every album of project id (id of theProject)
    logEvent("Found " & (count of theAlbumList) & " albums") of me
    if theSubfolderList is equal to {} then
    set end of ProjectFolders to processAlbums(theAlbumList, (theProjectPath & theProjectName & "/"), processOrder) of me as list
    else
    if theAlbumList is not equal to {} then
    set end of ProjectFolders to processAlbums(theAlbumList, (theProjectPath & theProjectName & "/"), processOrder) of me as list
    end if
    set end of ProjectFolders to processSubfolders(theSubfolderList, (theProjectPath & theProjectName & "/"), processOrder) of me as list
    end if
    if processOrder is equal to "projects" then
    cleanup(ProjectFolders, (theProjectPath & theProjectName & "/"), "all") of me
    else
    cleanup(ProjectFolders, (theProjectPath & theProjectName & "/"), "folder") of me
    end if
    end if
    set theCounter to theCounter + 1
    end repeat
    end tell
    logEvent("processProjects completed...") of me
    return arrayOfProjects
    end processProjects
    on exportImage(imageUUID, imageName, exportFolder, imageType, isAlbum, exportSettings, imageExt)
    set imageInfo to DB_lookupImageInfo(imageUUID) of me
    set imageTime to theImageDate of imageInfo as Unicode text
    set imageDate to date imageTime
    set isExported to 0
    set imageName to imageName & imageExt
    set theFile to POSIX file (exportFolder & imageName)
    tell application "Finder"
    set isUpdate to 0
    if not (exists theFile) then
    logEvent("Image does not exist in folder : " & exportFolder) of me
    set isUpdate to 1
    else
    logEvent("Get image modification date") of me
    do shell script "ls -l " & quoted form of (exportFolder & imageName)
    set imageFileDate to modification date of (info for theFile)
    if imageDate ≥ imageFileDate then
    logEvent("Image file date: " & imageFileDate as string) of me
    set isUpdate to 1
    end if
    end if
    if isUpdate = 1 then
    if exists theFile then
    move theFile to the trash
    end if
    if isAlbum is equal to "album" then
    logEvent("Creating a link for image: " & imageName) of me
    set theProjectFolder to theImagePath of imageInfo
    do shell script "ln " & quoted form of (theLibraryPath_G & theProjectFolder & "/" & imageName) & " " & quoted form of exportFolder
    else
    set isExported to 1
    logEvent("Exporting image: " & imageName) of me
    tell application "Aperture"
    if imageType is "master" then
    set settings to exportSettings
    export {image version id imageUUID} using settings to POSIX path of file exportFolder metadata embedded
    else
    set settings to exportSettings
    export {image version id imageUUID} using settings to POSIX path of file exportFolder metadata embedded
    end if
    end tell
    end if
    end if
    end tell
    return isExported
    end exportImage
    on DB_execute(SqlStatement)
    try
    set SqlScript to Sqlite_G & space & "-separator '|'" & space & (quoted form of ApertureLibrary_G) & space & (quoted form of SqlStatement) & " 2>&1"
    set SqlResult to do shell script SqlScript
    set theARray to {}
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ASCII character 13
    set SqlRecords to text items of SqlResult
    set AppleScript's text item delimiters to tid
    return SqlRecords
    on error s number i partial result p from f to t
    set s to "SQL Error: " & s
    logEvent(quoted form of (s)) of me
    end try
    end DB_execute
    on DB_record(SqlRecords, row, col)
    try
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "|"
    set SqlCols to text items of (item row of SqlRecords)
    set AppleScript's text item delimiters to tid
    return item col of SqlCols
    on error
    return {}
    end try
    end DB_record
    on DB_lookupRecord(SqlRecords, theReturnCol, theText, theCol)
    set theResult to ""
    repeat with theRow in items of SqlRecords
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "|"
    set theFields to text items of theRow
    set AppleScript's text item delimiters to tid
    if item theCol of theFields is equal to theText then
    set theResult to item theReturnCol of theFields
    exit repeat
    end if
    end repeat
    return theResult
    end DB_lookupRecord
    on processImages(theImageList, exportFolder, isAlbum, exportSettings)
    logEvent("processImages... : " & exportFolder) of me
    if exportSettings contains "JPEG" then
    set imageExt to ".jpg"
    else
    set imageExt to ".ANY"
    end if
    set arrayOfImages to {}
    with timeout of 6000 seconds
    set theCount to count of theImageList
    set theCounter to 1
    repeat with theImage in theImageList
    set imageUUID to id of theImage
    set imageName to name of theImage
    set end of arrayOfImages to imageName & imageExt
    logEvent("Processing image : " & imageName & " (" & theCounter & "/" & theCount & ")") of me
    set numExports_G to numExports_G + (exportImage(imageUUID, imageName, exportFolder, "version", isAlbum, exportSettings, imageExt) of me)
    set theCounter to theCounter + 1
    end repeat
    end timeout
    return arrayOfImages
    end processImages
    on processAlbums(theAlbumsList, theAlbumPath, processOrder)
    logEvent("processAlbums... : " & theAlbumPath) of me
    set arrayOfAlbums to {}
    tell application "Aperture"
    set theCount to count of theAlbumsList
    set theCounter to 1
    repeat with theAlbum in theAlbumsList
    set theAlbumName to name of theAlbum
    logEvent("Processing album : " & theAlbumName & " (" & theCounter & "/" & theCount & ")") of me
    set theCounter to theCounter + 1
    set AlbumObjects to {}
    set end of arrayOfAlbums to theAlbumName
    tell application "Finder"
    if not (exists (POSIX file (theAlbumPath & theAlbumName) of me)) then
    logEvent("creating new folder " & theAlbumName & " at " & theAlbumPath) of me
    make new folder at (POSIX file theAlbumPath of me) with properties {name:theAlbumName}
    end if
    end tell
    logEvent("Getting list of images...") of me
    set theImagesList to every image version of album id (id of theAlbum)
    logEvent("Found " & (count of theImagesList) & " images") of me
    if processOrder is equal to "albums" then
    set end of AlbumObjects to processImages(theImagesList, (theAlbumPath & theAlbumName & "/"), "album", "JPEG - Original Size") of me as list
    cleanup(AlbumObjects, (theAlbumPath & theAlbumName & "/"), "all") of me
    end if
    end repeat
    end tell
    logEvent("processAlbums completed...") of me
    return arrayOfAlbums
    end processAlbums
    on processSubfolders(theSubfoldersList, theSubfolderPath, processOrder)
    logEvent("processSubfolders... : " & theSubfolderPath) of me
    set arrayOfSubfolders to {}
    tell application "Aperture"
    set theCount to count of theSubfoldersList
    set theCounter to 1
    repeat with theSubfolder in theSubfoldersList
    set theSubfolderName to name of theSubfolder
    logEvent("Processing subfolder : " & theSubfolderName & " (" & theCounter & "/" & theCount & ")") of me
    set theCounter to theCounter + 1
    set end of arrayOfSubfolders to theSubfolderName
    tell application "Finder"
    if not (exists (POSIX file (theSubfolderPath & theSubfolderName) of me)) then
    logEvent("creating new folder " & theSubfolderName & " at " & theSubfolderPath) of me
    make new folder at (POSIX file theSubfolderPath of me) with properties {name:theSubfolderName}
    end if
    end tell
    set SubfoldersFolders to {}
    logEvent("Getting list of albums ...") of me
    set theAlbumsListOfSubfolder to every album of subfolder id (id of theSubfolder)
    logEvent("Found " & (count of theAlbumsListOfSubfolder) & " albums") of me
    logEvent("Getting list of subfolders...") of me
    set theSubfoldersListOfSubfolder to every subfolder of subfolder id (id of theSubfolder)
    logEvent("Found " & (count of theSubfoldersListOfSubfolder) & " subfolders") of me
    if theSubfoldersListOfSubfolder is equal to {} then
    set end of SubfoldersFolders to processAlbums(theAlbumsListOfSubfolder, (theSubfolderPath & theSubfolderName & "/"), processOrder) of me as list
    else
    if theAlbumsListOfSubfolder is not equal to {} then
    set end of SubfoldersFolders to processAlbums(theAlbumsListOfSubfolder, (theSubfolderPath & theSubfolderName & "/"), processOrder) of me as list
    end if
    set end of SubfoldersFolders to processSubfolders(theSubfoldersListOfSubfolder, (theSubfolderPath & theSubfolderName & "/"), processOrder) of me as list
    end if
    cleanup(SubfoldersFolders, (theSubfolderPath & theSubfolderName & "/"), "all") of me
    end repeat
    end tell
    logEvent("processSubfolders completed...") of me
    return arrayOfSubfolders
    end processSubfolders

    If you do externalize your Masters to folders anywhere (same drive, internal/external drive, multiple drives, whatever), never be tempted to use Finder to mess with them.
    As Frank said, use Relocate Masters.  Otherwise you'll confuse Aperture when it wakes up expecting Masters to be in certain places when they have moved elsewhere.
    It's possible to fix up the mess, but it's no fun!

  • Drag and Drop objects with JavaFX properties

    Has anyone tried to implement drag and drop functionality with objects containing JavaFX properties? The issue I'm running into is that the objects appear to need to be serializable, and the JavaFX properties are not serializable. I can implement Externalizable instead of Serializable, and basically serialize the values contained by the FX properties, but of course I lose any bindings by doing this (as the listeners underlying the bindings are not serialized).
    The [url http://docs.oracle.com/javafx/2/api/javafx/scene/input/Clipboard.html]javadocs for Clipboard state "In addition to the common or built in types, you may put any arbitrary data onto the clipboard (assuming it is either a reference, or serializable. See more about references later)" but I don't see any further information about references (and at any rate, this doesn't really make sense since anything that's serializable would be a reference anyway). Is there a special DataFormat I can use to specify a reference in the local JVM so the reference gets passed without serialization?
    I know this might not make sense without a code example; I just thought someone might have come across this closely enough to recognize the problem. I'll try to post a code example tonight...

    Here's pretty much the simplest example I can come up with. I have a real-world example of needing to do this, but the object model for the real example is quite a bit more complex.
    For the toy example, imagine we have a list of projects, some employees, and we want to assign each project to one or more employees. I have a Project class with a title and assignee. (In real life you can imagine other properties; due date, status, etc.) I'll keep a ListView with a bunch of unassigned projects (titles but assignees equal to null) and then a ListView for each of the employees.
    To assign a project to an employee, the user should be able to drag from the "master" list view to one of the employee list views. When the project is dropped, we'll create a new project, set the assignee, and bind the title of the new project to the title of the project which was dragged. (Remember we want to be able to assign a single project to multiple employees.)
    So here's the first shot:
    A couple of simple model classes
    Project.java
    import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    public class Project {
         private final StringProperty title ;
         private final ObjectProperty<Employee> assignee ;
         public Project(String title) {
              this.title = new SimpleStringProperty(this, "title", title);
              this.assignee = new SimpleObjectProperty<Employee>(this, "assignee");
         public Project() {
              this("");
         public StringProperty titleProperty() {
              return title ;
         public String getTitle() {
              return title.get() ;
         public void setTitle(String title) {
              this.title.set(title);
         public ObjectProperty<Employee> assigneeProperty() {
              return assignee ;
         public Employee getAssignee() {
              return assignee.get();
         public void setAssignee(Employee assignee) {
              this.assignee.set(assignee);
         @Override
         public String toString() {
              String t = title.get();
              Employee emp = assignee.get();
              if (emp==null) {
                   return t;
              } else {
                   return String.format("%s (%s)", t, emp.getName()) ;
    }Employee.java
    import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    public class Employee {
         private StringProperty name ;
         public Employee(String name) {
              this.name = new SimpleStringProperty(this,"name", name);
         public StringProperty nameProperty() {
              return name ;
         public String getName() {
              return name.get();
         public void setName(String name) {
              this.name.set(name);
    }and the application
    DnDExample.java
    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.control.TextField;
    import javafx.scene.input.ClipboardContent;
    import javafx.scene.input.DataFormat;
    import javafx.scene.input.DragEvent;
    import javafx.scene.input.Dragboard;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.input.TransferMode;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class DnDExample extends Application {
         private static final DataFormat PROJECT_DATA_FORMAT = new DataFormat("com.example.project"); // is there something special I can use here?
         @Override
         public void start(Stage primaryStage) {
              final HBox root = new HBox(5);
              final ListView<Project> allProjects = new ListView<Project>();
              final Employee fred = new Employee("Fred");
              final Employee ginger = new Employee("Ginger");
              final ListView<Project> fredsProjects = new ListView<Project>();
              final ListView<Project> gingersProjects = new ListView<Project>();
              final VBox employeeLists = new VBox(5);
              employeeLists.getChildren().addAll(new Label("Fred's Projects"), fredsProjects, new Label("Ginger's Projects"), gingersProjects);
              root.getChildren().addAll(allProjects, employeeLists);
              allProjects.setCellFactory(new Callback<ListView<Project>, ListCell<Project>>() {
                   @Override
                   public ListCell<Project> call(ListView<Project> listView) {
                        return new AllProjectListCell();
              allProjects.setEditable(true);
              final EventHandler<DragEvent> dragOverHandler = new EventHandler<DragEvent>() {
                   @Override
                   public void handle(DragEvent dragEvent) {
                        if (dragEvent.getDragboard().hasContent(PROJECT_DATA_FORMAT)) {
                             dragEvent.acceptTransferModes(TransferMode.COPY);
              fredsProjects.setOnDragOver(dragOverHandler);
              gingersProjects.setOnDragOver(dragOverHandler);
              fredsProjects.setOnDragDropped(new DragDropHandler(fred, fredsProjects.getItems()));
              gingersProjects.setOnDragDropped(new DragDropHandler(ginger, gingersProjects.getItems()));
              allProjects.getItems().addAll(new Project("Implement Drag and Drop"), new Project("Fix serialization problem"));
              Scene scene = new Scene(root, 600, 400);
              primaryStage.setScene(scene);
              primaryStage.show();
         public static void main(String[] args) {
              launch(args);
         private class DragDropHandler implements EventHandler<DragEvent> {
              private final Employee employee ;
              private final ObservableList<Project> itemList;
              DragDropHandler(Employee employee, ObservableList<Project> itemList) {
                   this.employee = employee ;
                   this.itemList = itemList ;
              @Override
              public void handle(DragEvent event) {
                   Dragboard db = event.getDragboard();
                   if (db.hasContent(PROJECT_DATA_FORMAT)) {
                        Project project = (Project) db.getContent(PROJECT_DATA_FORMAT);
                        Project assignedProject = new Project();
                        assignedProject.titleProperty().bind(project.titleProperty());
                        assignedProject.setAssignee(employee);
                        itemList.add(assignedProject);
         private class AllProjectListCell extends ListCell<Project> {
              private TextField textField ;
              private final EventHandler<MouseEvent> dragDetectedHandler ;
              AllProjectListCell() {               
                   this.dragDetectedHandler = new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent event) {
                             Dragboard db = startDragAndDrop(TransferMode.COPY);
                             ClipboardContent cc = new ClipboardContent();
                             cc.put(PROJECT_DATA_FORMAT, getItem());
                             db.setContent(cc);
                             event.consume();
                   this.setEditable(true);
              @Override
              public void updateItem(final Project project, boolean empty) {
                   super.updateItem(project, empty);
                   if (empty) {
                        setText(null);
                        setGraphic(null);
                        setOnDragDetected(null);
                   } else if (isEditing()) {
                        if (textField != null) {
                             textField.setText(getItem().getTitle());
                        setText(null) ;
                        setOnDragDetected(null);
                        setGraphic(textField);                    
                   } else {
                        setText(project.getTitle());
                        setOnDragDetected(dragDetectedHandler);
              @Override
              public void startEdit() {
                   super.startEdit();
                   if (!isEmpty()) {
                        textField = new TextField(getItem().getTitle());
                        textField.setMinWidth(this.getWidth()-this.getGraphicTextGap());
                        textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
                             @Override
                             public void changed(
                                       ObservableValue<? extends Boolean> observable,
                                       Boolean oldValue, Boolean newValue) {
                                  if (! newValue) {
                                       getItem().setTitle(textField.getText());
                                       commitEdit(getItem());
                        setText(null);
                        setGraphic(textField);
                        setOnDragDetected(null);
              @Override
              public void cancelEdit() {
                   super.cancelEdit();
                   if (!isEmpty()) {
                        setText(getItem().getTitle());
                        setGraphic(null);
                        setOnDragDetected(dragDetectedHandler);
                   } else {
                        setText(null);
                        setGraphic(null);
                        setOnDragDetected(null);
              @Override
              public void commitEdit(Project project) {
                   super.commitEdit(project);
                   if (!isEmpty()) {
                        setText(getItem().getTitle());
                        setGraphic(null);
                        setOnDragDetected(dragDetectedHandler);
    }If you try to drag from the list on the left to one of the lists on the right, it will fail pretty quickly and tell you that the data need to be Serializable.
    Simply adding "implements Serializable" to the Project and Employee classes doesn't work, as you find that SimpleStringProperty and SimpleObjectProperty are not Serializable. So instead I can use Externalizable:
    public class Project implements Externalizable {
    @Override
         public void writeExternal(ObjectOutput out) throws IOException {
              out.writeObject(title.get());
              out.writeObject(assignee.get());
         @Override
         public void readExternal(ObjectInput in) throws IOException,
                   ClassNotFoundException {
              setTitle((String)in.readObject());
              setAssignee((Employee)in.readObject());
    }and
    public class Employee implements Externalizable {
         @Override
         public void writeExternal(ObjectOutput out) throws IOException {
              out.writeObject(name.get());
         @Override
         public void readExternal(ObjectInput in) throws IOException,
                   ClassNotFoundException {
              setName((String) in.readObject());
    }This makes the drag and drop work, but if you drop a project on one of the employee lists, then edit the project title in the master list, the binding is not respected. This is because deserialization creates a new SimpleStringProperty for the title, which is not the property to which the title of the new Project object is bound.
    What I really want to do is to be able to drag and drop an object within the same JVM simply by passing the object by reference, rather than by serializing it. Is there a way to do this? Is there some DataFormat type I need?

  • Externalizable vs DataOutputStream/DataInputStream (Storable Interface)

    I have created an interface Storable as below which I use to save a complex Object to a byte array and ultimately to a database. The total processing time is 1hour and 5 minutes.
    public interface Storable
         void readData(DataInputStream in) throws IOException;
         void writeData(DataOutputStream out) throws IOException;
    I then swapped to Externalizable.
    I changed the top Object readData/writeData functions to
    readExternal and writeExternal.
    Then I added new readData/writeData functions to the contained Objects
    as below - so these objects are "new"ed and filled in by my code.
    void readData(InputObject in) throws IOException;
    void writeData(OutputObject out) throws IOException;
    Total processing time was reduced to 33minutes.
    Can anybody explain this >50% speed improvement?
    Also I would rather not use Externalizable so I can decouple the persisted data away from the Java code but it looks like one heck of a time penalty for doing so.

    The point is the only difference between the code I have written is that one is using
    ObjectInput/ObjectOutput (Externalizable) (34 minutes)
    the other is using
    DataOutputStream/DataInputStream (Storable) (1hour 5 minutes)
    and my code for the 2 methods is basically the same.
    This would lead to the conclusion that one of or both Java classes DataOutputStream/DataInputStream are very inefficient and I want to know why?

Maybe you are looking for

  • Oracle Listener Problem

    I am having a problem starting the Oracle Listener after a system crash on Windows NT. However, if I first connect to the internet and then try to restart, everything works ok. Why should I have to connect to the internet with my laptop in order to s

  • Video doesn't slow when added to timeline of different frame rate

    I'm having trouble understanding what's going on here.  I have a video shot at 59.94 fps, and I add it to a sequence that is set at 29.97 fps.  It plays back normally which makes sense if premiere is dropping frames by 1/2, but the drop frame indicat

  • What is the best way to work with avi-files?

    Hallo all, I'm new to this forum so before asking my question I'd like to say some words about myself: I'm not a native english speaker, so please excuse language mistakes I'll possibly make and feel free to ask if I'll write something which you don'

  • AppLocker Policy to block Malware

    I am in process of implementing Applocker in our Environment. To protect the clients from Malware attacks I want to configure a policy through which all the executable files can not run from User Profile. However I may have few executable files which

  • DateDiff to show working days

    Hello I have set up a calculated field in a report to show the number of days between a job start and end date. I am using T-SQL: =DateDiff("D", fields!jobstartdate.value, fields!jobenddate.value) This works fine, but is of course including weekends