4

In APEX there is great wrapper class to access the ToolingAPI written by Andrew Fawcett https://github.com/afawcett/apex-toolingapi

There are a lot of examples including one which shows how to edit an ApexClass. It uses a ToolingAPI.MetadataContainer to hold an ToolingAPI.ApexClassMember. This works great and is very fast.

Now I would like to adopt the same pattern to edit an ApexPage unsing again a ToolingAPI.MetadataContainer but now containing a ToolingAPI.ApexPageMember. Unfortunately this fails. Looking at the code of ToolingAPI.cls there are obvious differences.

Let's have a look on ToolingAPI.ApexClassMember

   public class ApexClassMember extends SObject_x implements ISerialize {
        public String            body;
        public String            content;
        public ApexClass         contentEntity;
        public String            contentEntityId;
        public Datetime          lastSyncDate;
        public ApexClassMetadata metadata;
        public MetadataContainer metadataContainer;
        public Id                metadataContainerId;        
        public SymbolTable       symbolTable;
        public ApexClassMember() {
            super(SObjectType.ApexClassMember);
        }
        public override void serialize(JSONGenerator jsonGen) {
            super.serialize(jsonGen);
            if(body!=null)
                jsonGen.writeStringField('body', body);
            if(content!=null)
                jsonGen.writeStringField('content', content);
            if(contentEntity!=null)
                jsonGen.writeObjectField('contentEntity', contentEntity);
            if(contentEntityId!=null)
                jsonGen.writeStringField('contentEntityId', contentEntityId);
            if(lastSyncDate!=null)
                jsonGen.writeDateTimeField('lastSyncDate', lastSyncDate);
            if(metadata!=null)
                jsonGen.writeObjectField('metadata', metadata);
            if(metadataContainer!=null)
                jsonGen.writeObjectField('metadataContainer', metadataContainer);
            if(metadataContainerId!=null)
                jsonGen.writeStringField('metadataContainerId', metadataContainerId);
            if(symbolTable!=null)
                jsonGen.writeObjectField('symbolTable', symbolTable);
        }
    }

Compared to ToolingAPI.ApexPageMember grabbed directly from https://raw.githubusercontent.com/afawcett/apex-toolingapi/master/src/classes/ToolingAPI.cls (as of 2014-07-09 20:00 CEST) it's quite less:

public class ApexPageMember extends SObject_x{
    public String            body;
    public String            content;
    public ApexPage          contentEntity;
    public String            contentEntityId;
    public DateTime          lastSyncDate;
    public Metadata          metadata;
    public MetadataContainer metadataContainer;
    public Id                metadataContainerId;
    public ApexPageMember() {
        super(SObjectType.ApexPageMember);
    }
}

Obviously the implementation of ISerialize is missing and the override of serialize(JSONGenerator jsonGen) which seem to be crucial to get the proper callout compiled. I suppose this is "under construction".

So what has to be done to make it work?

2

Maybe this could be interesting for @AndyFawcett (https://salesforce.stackexchange.com/users/286/andrew-fawcett) the author of ToolingAPI.cls. I just changed the code like this:

 public class ApexPageMember extends SObject_x  implements ISerialize {
    public String            body;
    public String            content;
    public ApexPage          contentEntity;
    public String            contentEntityId;
    public DateTime          lastSyncDate;
    public Metadata          metadata;
    public MetadataContainer metadataContainer;
    public Id                metadataContainerId;
    public ApexPageMember() {
        super(SObjectType.ApexPageMember);
    }
    public override void serialize(JSONGenerator jsonGen) {
        super.serialize(jsonGen);
        if(body!=null)
            jsonGen.writeStringField('body', body);
        if(content!=null)
            jsonGen.writeStringField('content', content);
        if(contentEntity!=null)
            jsonGen.writeObjectField('contentEntity', contentEntity);
        if(contentEntityId!=null)
            jsonGen.writeStringField('contentEntityId', contentEntityId);
        if(lastSyncDate!=null)
            jsonGen.writeDateTimeField('lastSyncDate', lastSyncDate);
        if(metadata!=null)
            jsonGen.writeObjectField('metadata', metadata);
        if(metadataContainer!=null)
            jsonGen.writeObjectField('metadataContainer', metadataContainer);
        if(metadataContainerId!=null)
            jsonGen.writeStringField('metadataContainerId', metadataContainerId);
    }
}

and it works fine for me calling it like that:

 ToolingAPI.ApexPageMember apexPageMember = new ToolingAPI.ApexPageMember(); // Create ApexPageMember and associate them with the MetadataContainer     
 apexPageMember.Body                = fileSaveBody;
 apexPageMember.ContentEntityId     = item.id;
 apexPageMember.MetadataContainerId = containerId;      
 ToolingAPI.SaveResult apexClassMemberSaveResult = tool.createSObject(apexPageMember);

If someone notice anything I was missing, please let me know.

2
  • The code is up on github and I'm sure @andrewfawcett would love community help with issues. Have you submitted a pull request with your changes to he can incorporate them into the master package? Jul 9 '14 at 21:54
  • @AndrewFawcett you are welcome! If you patch the ToolingAPI.cls, please also have a look at ApexComponentMember, where the same changes should be applied. After that in my tests I was also able to save components. Let me know, if you have any questions. Thanks again for that Class, it really rocks!
    – Uwe Heim
    Jul 11 '14 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.