Implementing a Microsoft .NET Application using the Alfresco Web Services

Exclusive offer: get 50% off this eBook here
Alfresco 3 Web Services

Alfresco 3 Web Services — Save 50%

Build Alfresco applications using Web Services, WebScripts and CMIS

$35.99    $18.00
by Piergiorgio Lucidi Ugo Cei | August 2010 | Content Management Open Source

This article by Ugo Cei and Piergiorgio Lucidi, authors of the book Alfresco 3 Web Services, will teach you how to use the Alfresco Web Services API from your Microsoft .NET application. It will also show you how to configure your development environment using the open source IDE SharpDevelop. The .NET sample is a standard application that performs operations against the repository.

(For more resources on Alfresco, see here.)

For the first step, you will see how to set up the .NET project in the development environment. Then when we take a look at the sample code, we will learn how to perform the following operations from your .NET application:

  • How to authenticate users
  • How to search contents
  • How to manipulate contents
  • How to manage child associations

Setting up the project

In order to execute samples included with this article, you need to download and install the following software components in your Windows operating system:

  • Microsoft .NET Framework 3.5
  • Web Services Enhancements (WSE) 3.0 for Microsoft .NET
  • SharpDevelop 3.2 IDE

The Microsoft .NET Framework 3.5 is the main framework used to compile the application, and you can download it using the following URL:
http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en.

Before importing the code in the development environment, you need to download and install the Web Services Enhancements (WSE) 3.0, which you can find at this address:
http://www.microsoft.com/downloads/details.aspx?FamilyID=018a09fd-3a74-43c5-8ec1-8d789091255d.

You can find more information about the Microsoft .NET framework on the official site at the following URL: http://www.microsoft.com/net/. From this page, you can access the latest news and the Developer Center where you can find the official forum and the developer community.

SharpDevelop 3.2 IDE is an open source IDE for C# and VB.NET, and you can download it using the following URL:
http://www.icsharpcode.net/OpenSource/SD/Download/#SharpDevelop3x.

Once you have installed all the mentioned software components, you can import the sample project into SharpDevelop IDE in the following way:

  • Click on File | Open | Project/Solution
  • Browse and select this file in the root folder of the samples: AwsSamples.sln
  • Now you should see a similar project tree in your development environment:

    Implementing a Microsoft .NET Application using the Alfresco Web Services

    More information about SharpDevelop IDE can be found on the official site at the following address: http://www.icsharpcode.net/opensource/sd/. From this page, you can download different versions of the product; which SharpDevelop IDE version you choose depends on the .NET version which you would like to use. You can also visit the official forum to interact with the community of developers.
    Also, notice that all the source code included with this article was implemented extending an existent open source project named dotnet. The dotnet project is available in the Alfresco Forge community, and it is downloadable from the following address:
    http://forge.alfresco.com/projects/dotnet/.

    Testing the .NET sample client

    Once you have set up the .NET solution in SharpDevelop, as explained in the previous section, you can execute all the tests to verify that the client is working correctly. We have provided a batch file named build.bat to allow you to build and run all the integration tests. You can find this batch file in the root folder of the sample code.

    Notice that you need to use a different version of msbuild for each different version of the .NET framework. If you want to compile using the .NET Framework 3.5, you need to set the following path in your environment:

    set PATH=%PATH%;%WinDir%\Microsoft.NET\Framework\v3.5

    Otherwise, you have to set .NET Framework 2.0 using the following path:

    set PATH=%PATH%;%WinDir%\Microsoft.NET\Framework\v2.0.50727

    We are going to assume that Alfresco is running correctly and it is listening on host localhost and on port 8080. Once executed, the build.bat program should start compiling and executing all the integration tests included in this article. After a few seconds have elapsed, you should see the following output in the command line:

    ...
    ...
    ...
    *****************
    * Running tests *
    *****************

    NUnit version 2.5.5.10112
    Copyright (C) 2002-2009 Charlie Poole.
    Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A.
    Vorontsov.
    Copyright (C) 2000-2002 Philip Craig.
    All Rights Reserved.


    Runtime Environment -
    OS Version: Microsoft Windows NT 5.1.2600 Service Pack 2
    CLR Version: 2.0.50727.3053 ( Net 2.0 )

    ProcessModel: Default DomainUsage: Single
    Execution Runtime: net-2.0
    ............
    Tests run: 12, Errors: 0, Failures: 0, Inconclusive: 0, Time: 14.170376
    seconds

    Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0

    ********
    * Done *
    ********

    As you can see from the project tree, you have some of the following packages:

    • Search
    • Crud
    • Association

    The Search package shows you how to perform queries against the repository.

    The Crud package contains samples related to all the CRUD operations that show you how to perform basic operations; namely, how to create/get/update/remove nodes in the repository.

    The Association package shows you how to create and remove association instances among nodes.

    Searching the repository

    Once you have authenticated a user, you can start to execute queries against the repository. In the following sample code, we will see how to perform a query using the RepositoryService of Alfresco:

    RepositoryService repositoryService = WebServiceFactory.
    getRepositoryService();

    Then we need to create a store where we would like to search contents:

    Store spacesStore = new Store(StoreEnum.workspace, "SpacesStore");

    Now we need to create a Lucene query. In this sample, we want to search the Company Home space, and this means that we have to execute the following query:

    String luceneQuery = "PATH:\"/app:company_home\"";

    In the next step, we need to use the query method available from the RepositoryService. In this way, we can execute the Lucene query and we can get all the results from the repository:

    Query query =
    new Query(Constants.QUERY_LANG_LUCENE, luceneQuery);

    QueryResult queryResult =
    repositoryService.query(spacesStore, query, false);

    You can retrieve all the results from the queryResult object, iterating the ResultSetRow object in the following way:

    ResultSet resultSet = queryResult.resultSet;
    ResultSetRow[] results = resultSet.rows;

    //your custom list
    IList<CustomResultVO> customResultList =
    new List<CustomResultVO>();

    //retrieve results from the resultSet
    foreach(ResultSetRow resultRow in results)
    {
    ResultSetRowNode nodeResult = resultRow.node;

    //create your custom value object
    CustomResultVO customResultVo = new CustomResultVO();
    customResultVo.Id = nodeResult.id;
    customResultVo.Type = nodeResult.type;

    //retrieve properties from the current node
    foreach(NamedValue namedValue in resultRow.columns)
    {
    if (Constants.PROP_NAME.Equals(namedValue.name))
    {
    customResultVo.Name = namedValue.value;
    } else if (Constants.PROP_DESCRIPTION.Equals(namedValue.name))
    {
    customResultVo.Description = namedValue.value;
    }
    }

    //add the current result to your custom list
    customResultList.Add(customResultVo);
    }

    In the last sample, we iterated all the results and we created a new custom list with our custom value object CustomResultVO.

    More information about how to build Lucene queries can be found at this URL: http://wiki.alfresco.com/wiki/Search.

    Performing operations

    We can perform various operations on the repository. They are documented as follows:

    Authentication

    For each operation, you need to authenticate users before performing all the required operations on nodes. The class that provides the authentication feature is named AuthenticationUtils, and it allows you to invoke the startSession and endSession methods:

    String username = "johndoe";
    String password = "secret";
    AuthenticationUtils.startSession(username, password);

    try{

    }
    finally
    {
    AuthenticationUtils.endSession();
    }

    Remember that the startSession method requires the user credentials: the username as the first argument and the password as the second.

    Notice that the default endpoint address of the Alfresco instance is as follows:

    http://localhost:8080/alfresco

    If you need to change the endpoint address, you can use the WebServiceFactory class invoking the setEndpointAddress method to set the new location of the Alfresco repository.

    Alfresco 3 Web Services Build Alfresco applications using Web Services, WebScripts and CMIS
    Published: August 2010
    eBook Price: $35.99
    Book Price: $59.99
    See more
    Select your format and quantity:

    (For more resources on Alfresco, see here.)

    CRUD operations

    Inside the Crud package of the sample project, you can see how to invoke basic operations to manipulate contents. In this section, we will see how to perform all the following operations on nodes:

    • Create
    • Update
    • Copy
    • Move
    • Remove

    Creating nodes

    In order to create nodes in the repository, you need to create a CMLCreate object. You need to use the Content Manipulation Language of Alfresco to manipulate content using the Web Services API. So, in this case, we want to create a node with some basic properties without any associated content.

    The first object defined in the sample is the Store object. The Store is used to define where we want to create the new node. The SpacesStore is the store for all the latest versions of nodes:

    Store spacesStore = new Store(StoreEnum.workspace, "SpacesStore");

    Then we need to provide properties for the new node:

    String name = "AWS Book " + DateTime.Now.Ticks;
    String description =
    "This is a content created with a sample of the book";

    //custom value object
    CreateSampleVO createSampleVo = Builder.BuildCreateSampleVO(name,
    name, description);

    The Builder class shows you an example of how you can create your custom object getting the new properties value (BuildCreateSampleVO method). Also, inside the same class, there is another method to create the NamedValue array required in the CMLCreate object. In the following snippet, you can see the Builder class:

    public static class Builder
    {
    public static NamedValue[] BuildCustomProperties(CreateSampleVO
    createSampleVo)
    {
    NamedValue[] properties = new NamedValue[3];
    properties[0] = Utils.createNamedValue(Constants.PROP_NAME,
    createSampleVo.Name);
    properties[1] = Utils.createNamedValue(Constants.PROP_TITLE,
    createSampleVo.Title);
    properties[2] = Utils.createNamedValue(Constants.PROP_
    DESCRIPTION,
    createSampleVo.Description);
    return properties;
    }

    public static CreateSampleVO BuildCreateSampleVO(String name,
    String title, String description)
    {
    CreateSampleVO createSample = new CreateSampleVO();
    createSample.Name = name;
    createSample.Title = title;
    createSample.Description = description;
    return createSample;
    }

    In the next step, we are building the ParentReference object, which is the parent of the new node:

    try
    {
    ParentReference parent = new ParentReference(
    spacesStore,
    null,
    "/app:company_home",
    Constants.ASSOC_CONTAINS,
    "{" + Constants.NAMESPACE_CONTENT_MODEL + "}" + name
    );

    //build properties
    NamedValue[] properties = Builder.BuildCustomProperties(createSam
    pleVo);

    Constants.ASSOC_CONTAINS is the default child association cm:contains, which is defined in the default content model in Alfresco. This association allows you to add new nodes (children) in spaces (parents).

    In order to create a new node, you need to use the CMLCreate object. For this object, you need to provide a parent for the new node, a content type for the node, and all the node properties:

    //create operation
    CMLCreate create = new CMLCreate();
    create.id = "1";
    create.parent = parent;
    create.type = Constants.TYPE_CONTENT;
    create.property = properties;

    Constants.TYPE_CONTENT is a constant value that allows you to define new generic content in Alfresco with the following QName value: cm:content.

    Now we have a complete CMLCreate object, that is, an operation for the CML language. We need to encapsulate this object in a new generic CML object to execute the operation:

    CML cml = new CML();
    cml.create = new CMLCreate[]{ create };

    Finally, we can invoke the update method of the RepositoryService to perform the operation against the repository:

    UpdateResult[] result = WebServiceFactory.getRepositoryService().
    update(cml);

    Creating content

    In the previous paragraph, you learned how to create nodes with properties, but if you need to store a node with a related content—for example, a document—you need to upload the file to the repository.

    To accomplish this task, you can follow one of two methods:

    • Using the CMLWriteContent object
    • Using the ContentService

    Creating content using CML

    If you want to encapsulate the content in a unique request for the creation of the node and its content, you have to add an instance of the CMLWriteContent object inside the previous CML request.

    For the first step, you need to create an instance of the Reference object to point to the new node contained in the previous CMLCreate object:

    //create the node reference
    Reference reference = new Reference();
    reference.store = spacesStore;
    reference.path = "/app:company_home/cm:"+ISO9075.Encode(name);"/app:
    company_home/cm:"+ISO9075.Encode(name);

    The path field is provided encoding the space names in the ISO 9075 format because Alfresco stores node paths using XPath. Alfresco provides you with a utility class ISO9075 to allow you to encode and decode space names in the correct way.

    In the following section, you need to provide a Predicate object as the group of the involved nodes. In this case, we have only a node reference:

    //create the predicate
    Predicate predicate = new Predicate();
    predicate.Items = new Reference[]{ reference };

    In this step, we are creating the ContentFormat to create all the indexes correctly for the current content:

    //set mime type and encoding for indexing
    ContentFormat format = new ContentFormat(mimeType, encoding);

    Now that we have all the needed objects, we can build the CMLWriteContent object, and we can add this instance to the CML object.

    //write operation
    CMLWriteContent writeContent = new CMLWriteContent();
    writeContent.format = format;
    writeContent.where = predicate
    ;
    writeContent.property = Constants.PROP_CONTENT;
    writeContent.content = new ASCIIEncoding().GetBytes("This is the
    content for the new node");


    //build the CML object
    CML cml = new CML();
    cml.create = new CMLCreate[]{ create };
    cml.writeContent = new CMLWriteContent[]{ writeContent };

    Finally, we can execute the update method:

    UpdateResult[] result = WebServiceFactory.getRepositoryService().
    update(cml);

    Creating content using ContentService

    Another way to create content is to use the ContentService as a second request after you performed the creation of the node. So, in this case, we are creating content at two occasions: during the first request we will create the node with all the properties and during the second request we will upload the content.

    Let's say that we have created and performed a previous CMLCreate operation in the repository:

    //perform a CML update for the CMLCreate operation
    UpdateResult[] result = WebServiceFactory.getRepositoryService().
    update(cml);

    From the previous operation, we can get the new node reference:

    //get the new node reference
    Alfresco.ContentWebService.Reference referenceForContent = Alfresco.
    ContentWebService.Reference.From(
    result[0].destination);

    In the next section, we create the ContentFormat object:

    Alfresco.ContentWebService.ContentFormat format = new Alfresco.
    ContentWebService.ContentFormat(mimeType, encoding);

    Finally, we can get ContentService from WebServiceFactory, and then we can use it to upload the content. We have to provide the node reference, the content property, and the stream for the content:

    Alfresco.ContentWebService.Content content = WebServiceFactory.
    getContentService().write(

    referenceForContent,
    Constants.PROP_CONTENT,
    new ASCIIEncoding().GetBytes(
    "This is the content for the new node"),
    format
    );

    Notice that creating content using ContentService can cause problems with the atomicity of the operation. If you have a problem during the execution of the write method, the node can exist in the repository and not the content.

    Updating nodes

    Once you have stored content in the repository and you need to update one of these existent nodes, you must provide an instance of the CMLUpdate object. To update a node in Alfresco, you can:

    • Perform a clean update of the node and its content
    • Create a new version for the involved node

    Updating nodes without versioning

    In the following sample code, you can see how to update existent properties values for a node previously created using the CMLUpdate object:

    //create a predicate with the first CMLCreate result
    Reference referenceForNode = result[0].destination;

    Predicate sourcePredicate = new Predicate(
    new Reference[]{ referenceForNode },
    spacesStore,
    null
    );

    Reference referenceForTargetSpace = result[1].destination;

    //reference for the target space
    ParentReference targetSpace = new ParentReference();
    targetSpace.store = spacesStore;
    targetSpace.path = referenceForTargetSpace.path;
    targetSpace.associationType = Constants.ASSOC_CONTAINS;
    targetSpace.childName = name;

    To create a parent reference, as you can see in the previous snippet, you must provide:

    • The Store object for the destination
    • The path of the parent node
    • The type of the association that you want to use between the space and the node
    • The child name for the current instance of the association

    In the following section, we are creating the new properties values for the node:

    name = "AWS Book - Changed by CMLUpdate " + DateTime.Now.Ticks;
    createSampleVo.Name = name;
    createSampleVo.Title = name;
    createSampleVo.Description = "Changed by CMLUpdate " + description;

    Now, we need to create a CMLUpdate object to set all the new properties:

    //update node
    CMLUpdate update = new CMLUpdate();
    update.property = Builder.BuildCustomProperties(createSampleVo);
    update.where = sourcePredicate;

    Finally, we can execute the update method to perform the CML operation:

    CML cmlUpdate = new CML();
    cmlUpdate.update = new CMLUpdate[]{ update };

    //perform a CML update
    WebServiceFactory.getRepositoryService().update(cmlUpdate);

    Updating nodes with versioning

    If you need to create a new version of an existing node, you can add the versionable aspect to the node. In this way, the repository will change the behavior for the involved node, creating a new version for each update. The repository will keep all the old versions for the node, creating a version history.

    Assuming that we have an existing node previously created in the repository, we have to provide the same object seen in the previous paragraph, but by adding a new CML object named CMLAddAspect. This new object will add a new behavior for the node, and specifically, it will add the versionable aspect:

    //create a predicate with the first CMLCreate result
    Reference referenceForNode = result[0].destination;
    Predicate sourcePredicate = new Predicate(new Reference[]{
    referenceForNode }, spacesStore, null);

    Reference referenceForTargetSpace = result[1].destination;

    //reference for the target space
    ParentReference targetSpace = new ParentReference();
    targetSpace.store = spacesStore;
    targetSpace.path = referenceForTargetSpace.path;
    targetSpace.associationType = Constants.ASSOC_CONTAINS;
    targetSpace.childName = name;
    name = "AWS Book - Changed by CMLUpdate " + DateTime.Now.Ticks;

    createSampleVo.Name = name;
    createSampleVo.Title = name;
    createSampleVo.Description =
    "Changed by CMLUpdate " + description;

    In the following snippet, we will create the CMLAddAspect object providing the QName of the aspect and the group of all the involved nodes (sourcePredicate). This is the object that will add the new behavior for this node:

    CMLAddAspect aspect = new CMLAddAspect();
    aspect.aspect = Constants.ASPECT_VERSIONABLE;
    aspect.where = sourcePredicate;

    Finally, we can add CMLAddAspect to the CML object, and then invoke the update method:

    //update node
    CMLUpdate update = new CMLUpdate();
    update.property = Builder.BuildCustomProperties(createSampleVo);
    update.where = sourcePredicate;

    CML cmlUpdate = new CML();
    cmlUpdate.addAspect = new CMLAddAspect[]{ aspect };
    cmlUpdate.update = new CMLUpdate[]{ update };

    //perform a CML update WebServiceFactory.getRepositoryService().
    update(cmlUpdate);

    Copying nodes

    Creating copies for nodes is an operation that can be performed using another CML object defined for this feature, which is named CMLCopy. As in the previous samples, we are assuming that we have an existing node in the repository and we want to copy it to a different space.

    We start by getting the node reference of the existing node at its new target space:

    //create a predicate with the first CMLCreate result
    Reference referenceForNode = result[0].destination;
    Predicate sourcePredicate = new Predicate(new Reference[]{
    referenceForNode }, spacesStore, null);

    //reference for the space
    Reference referenceForTargetSpace = result[1].destination;

    //reference for the target space
    ParentReference targetSpace = new ParentReference();
    targetSpace.store = spacesStore;
    targetSpace.path = referenceForTargetSpace.path;
    targetSpace.associationType = Constants.ASSOC_CONTAINS;
    targetSpace.childName = name;

    Next we create the CMLCopy instance setting the where field with the group of source nodes that we want to copy from and the to field with the target space for all the copied nodes:

    //copy content
    CMLCopy copy = new CMLCopy();
    copy.where = sourcePredicate;
    copy.to = targetSpace;

    Finally, we create the array of CMLCopy objects. Then we perform this operation using the update method:

    CML cmlCopy = new CML();
    cmlCopy.copy = new CMLCopy[]{copy};

    //perform a CML update to move the node WebServiceFactory.
    getRepositoryService().update(cmlCopy);

    Moving nodes

    The move operation is performed using the CMLMove object. In the same way, as we saw in the previous paragraph, you have to provide two mandatory objects:

    • A predicate for the group of source nodes that you want to move
    • A target space for the destination

    In this first step, you need to create a predicate for the involved node:

    //create a predicate with the first CMLCreate result
    Reference referenceForNode = result[0].destination;
    Predicate sourcePredicate = new Predicate(new Reference[]{
    referenceForNode }, spacesStore, null);

    Then we create a parent reference as the new target space for the node:

    //create a reference for space
    Reference referenceForTargetSpace = result[1].destination;

    //reference for the target space
    ParentReference targetSpace = new ParentReference();
    targetSpace.store = spacesStore;
    targetSpace.path = referenceForTargetSpace.path;
    targetSpace.associationType = Constants.ASSOC_CONTAINS;
    targetSpace.childName = name;

    Next we create the CMLMove object, and we can set all the required fields:

    //move content
    CMLMove move = new CMLMove();
    move.where = sourcePredicate;
    move.to = targetSpace;

    Finally, we create the CML object by setting the move operation. Then we perform the following operation using the update method:

    CML cmlMove = new CML();
    cmlMove.move = new CMLMove[]{move};

    //perform a CML update to move the node WebServiceFactory.
    getRepositoryService().update(cmlMove);

    Removing nodes

    CMLDelete is the CML object that can be used to remove existing nodes in the repository. In the following sample, you will see how to remove a node from the repository. The unique field required for this operation is the predicate for the involved nodes:

    //create a predicate
    Reference reference = result[0].destination;
    Predicate predicate = new Predicate(new Reference[]{ reference },
    spacesStore, null);

    In next section, we create the CMLDelete object, setting the where field with the previous predicate:

    //delete content
    CMLDelete delete = new CMLDelete();
    delete.where = predicate;

    Finally, we build the CML object to use the update method:

    CML cmlRemove = new CML();
    cmlRemove.delete = new CMLDelete[]{delete};
    //perform a CML update to remove the node WebServiceFactory.
    getRepositoryService().update(cmlRemove);

    Managing child associations

    In this section, we will see how to manage child associations. You learned that a child association is a bidirectional association between a parent and its children.

    The two CML objects used to manage child associations are:

    1. CMLAddChild.
    2. CMLRemoveChild.

    CMLAddChild is used to add children to a parent, and CMLRemoveChild is used to remove children from a parent.

    Adding child nodes

    In the following sample, we want to associate two existent nodes. sourcePredicate is the predicate for the child nodes and targetSpace is the parent node:

    Reference referenceForNode = result[0].destination;

    Predicate sourcePredicate = new Predicate(new Reference[]{
    referenceForNode }, spacesStore, null);

    Reference referenceForTargetSpace = result[1].destination;

    //reference for the target space
    ParentReference targetSpace = new ParentReference();
    targetSpace.store = spacesStore;
    targetSpace.path = referenceForTargetSpace.path;
    targetSpace.associationType = Constants.ASSOC_CONTAINS;
    targetSpace.childName = name;

    In the next section, we will create the CMLAddChild object, setting the sourcePredicate and the targetSpace as its fields:

    //add child
    CMLAddChild addChild = new CMLAddChild();
    addChild.where = sourcePredicate;
    addChild.to = targetSpace;


    CML cmlAddChild = new CML();
    cmlAddChild.addChild = new CMLAddChild[]{ addChild };

    //perform a CML update to add the node WebServiceFactory.
    getRepositoryService().update(cmlAddChild);

    After the execution of the update method, all the involved nodes are associated by a new association instance. The child name will be the identifier for the new association instance.

    Removing child nodes

    Once you have associated nodes with one or more parents, you can remove children from a parent using the CMLRemoveChild object. You have to define:

    • A predicate for all the nodes that you want to remove (where)
    • A target space for the parent (Item)

    In the following snippet, you can see how to get these required objects:

    //reference for the target space
    ParentReference targetSpace = new ParentReference();
    targetSpace.store = spacesStore;
    targetSpace.path = referenceForTargetSpace.path;
    targetSpace.associationType = Constants.ASSOC_CONTAINS;
    targetSpace.childName = name;

    Reference refUpdate = resultAddChild[0].destination;

    Predicate nodeToRemove = new Predicate(new Reference[]{ refUpdate },
    spacesStore, null);

    Now we can create the CMLRemoveChild instance, and we can perform the operation:

    //remove child
    CMLRemoveChild removeChild = new CMLRemoveChild();
    removeChild.Item = targetSpace;
    removeChild.where = nodeToRemove;


    CML cmlRemoveChild = new CML();
    cmlRemoveChild.removeChild = new CMLRemoveChild[]{ removeChild };

    //perform a CML update to remove the node WebServiceFactory.
    getRepositoryService().update(cmlRemoveChild);

    Summary

    In this article, we discussed an example of a .NET application built on top of Alfresco using the Alfresco Web Services API. The article introduced an overview about how to set up the sample project in your development environment using the open source IDE SharpDevelop. Then it describes how to manipulate contents using .NET. Specifically, you learned the following topics:

    • How to set up the sample project in your .NET environment
    • How to perform queries using the Lucene query language
    • How to perform basic operations to manipulate content
    • How to add and remove child nodes from parents

    Further resources on this subject:


    Alfresco 3 Web Services Build Alfresco applications using Web Services, WebScripts and CMIS
    Published: August 2010
    eBook Price: $35.99
    Book Price: $59.99
    See more
    Select your format and quantity:

    About the Author :


    Piergiorgio Lucidi

    Piergiorgio Lucidi is an open source ECM Specialist at Sourcesense. Sourcesense is a European open source systems integrator providing consultancy, support, and services around key open source technologies.

    He works as Software Engineer, and he has 8 years of experience in the areas of Enterprise Content Management (ECM), system integrations, web, and mobile applications. He is an expert in integrating ECM solutions in web and portal applications.

    He contributes as PMC member, Project Leader, and Committer at the Apache Software Foundation for the project Apache ManifoldCF; he also contributes on ECM connectors such as CMIS, Alfresco, and ElasticSearch. He is a Project Leader and Committer of the JBoss Community, and he contributes to some of the projects of the JBoss Portal platform.

    He is a Speaker at conferences dedicated to ECM, Java, Spring Framework, and open source products and technologies.

    He is an Author, Technical Reviewer, and Affiliate Partner at Packt Publishing, for whom he wrote the technical book Alfresco 3 Web Services. As Technical Reviewer, he contributed to both Alfresco 3 Cookbook and Alfresco Share. As Affiliate Partner, he writes and publishes book reviews on his website Open4Dev (http://www.open4dev.com/).

    Ugo Cei

    Ugo Cei is Solutions Delivery Manager at Sourcesense Italy. He has over 20 years of experience in the IT sector. His areas of expertise include Web application development, content management systems, database, and search technologies. He has a Ph.D. in Engineering from the University of Pavia, Italy.Ugo is a long-time active contributor to numerous Open Source project and a member of the Apache Software Foundation.Besides his interests in computer-related matters, Ugo is a passionate photographer. He sometimes dreams of leaving the IT field to pursue his passion full-time, and travel the world with a camera.

    Books From Packt

    WordPress 3 Site Blueprints
    WordPress 3 Site Blueprints

    The Oracle Universal Content Management Handbook
    The Oracle Universal Content Management Handbook

    Plone 3 Intranets
    Plone 3 Intranets

    Joomla! 1.5 Site Blueprints
    Joomla! 1.5 Site Blueprints

    jQuery 1.4 Reference Guide
    jQuery 1.4 Reference Guide

    Joomla! Social Networking with JomSocial
    Joomla! Social Networking with JomSocial

    Agile Web Application Development with Yii1.1 and   PHP5
    Agile Web Application Development with Yii1.1 and PHP5

    Nginx HTTP Server
    Nginx HTTP Server

    Your rating: None Average: 4 (1 vote)
    i want to ask by
    i have been installed Microsoft WSE, .NET framework, and sharpdeveloper, but i can't find Awsexamples.sln. where is the location of the AwsSamples.sln

    Post new comment

    CAPTCHA
    This question is for testing whether you are a human visitor and to prevent automated spam submissions.
    k
    Y
    D
    H
    A
    c
    Enter the code without spaces and pay attention to upper/lower case.
    Code Download and Errata
    Packt Anytime, Anywhere
    Register Books
    Print Upgrades
    eBook Downloads
    Video Support
    Contact Us
    Awards Voting Nominations Previous Winners
    Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
    Resources
    Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software