/*
 * Copyright (C) 2005-2007 Alfresco Software Limited.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

 * As a special exception to the terms and conditions of version 2.0 of 
 * the GPL, you may redistribute this Program in connection with Free/Libre 
 * and Open Source Software ("FLOSS") applications as described in Alfresco's 
 * FLOSS exception.  You should have recieved a copy of the text describing 
 * the FLOSS exception, and it is also available here: 
 * http://www.alfresco.com/legal/licensing"
 */
package org.alfresco.example;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.debug.NodeStoreInspector;
import org.springframework.context.ApplicationContext;

/**
 * A quick example of how to
 * <ul>
 *   <li>get hold of the repository service</li>
 *   <li>initialise a model</li>
 *   <li>create nodes</li>
 *   <li>load in some content</li>
 * </ul>
 * <p>
 * <i>
 * All the normal checks for missing resources and so forth have been left out in the interests
 * of clarity of demonstration.
 * </i>
 * <p>
 * To change the model being used, make changes to the <b>dictionaryDAO</b> bean in the
 * application contenxt XML file.  For now, this example is written against the
 * generic <code>alfresco/model/contentModel.xml</code>.
 * <p>
 * The content store location can also be set in the application context.
 * 
 * 
 * @author Derek Hulley
 */
public class SimpleExampleWithContent
{
    private static final String NAMESPACE = "http://www.alfresco.org/test/SimpleExampleWithContent";
    
    public static void main(String[] args)
    {
        // initialise app content 
        ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
        // get registry of services
        final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
        
        // begin a UserTransaction
        // All the services are set to create or propogate the transaction.
        // This transaction will be recognised and propogated
        // The TransactionUtil takes care of the catching and rollback, etc
        TransactionService transactionService = serviceRegistry.getTransactionService();
        TransactionWork<Object> exampleWork = new TransactionWork<Object>()
        {
            public Object doWork() throws Exception
            {
                doExample(serviceRegistry);
                return null;
            }
        };
        TransactionUtil.executeInUserTransaction(transactionService, exampleWork);
        System.exit(0);
    }

    private static void doExample(ServiceRegistry serviceRegistry) throws Exception
    {
        // get individual, required services
        NodeService nodeService = serviceRegistry.getNodeService();
        ContentService contentService = serviceRegistry.getContentService();

        // authenticate
        AuthenticationService authenticationService = serviceRegistry.getAuthenticationService();
        authenticationService.authenticate("admin", "admin".toCharArray());
        
        // create a store, if one doesn't exist
        StoreRef storeRef = new StoreRef(
                StoreRef.PROTOCOL_WORKSPACE,
                "SimpleExampleWithContent-" + GUID.generate());
        if (!nodeService.exists(storeRef))
        {
            nodeService.createStore(storeRef.getProtocol(), storeRef.getIdentifier());
        }
        
        // get the root node from which to hang the next level of nodes
        NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
        
        Map<QName, Serializable> nodeProperties = new HashMap<QName, Serializable>(7);
        
        // add a simple folder to the root node
        nodeProperties.clear();
        nodeProperties.put(ContentModel.PROP_NAME, "My First Folder");
        ChildAssociationRef assocRef = nodeService.createNode(
                rootNodeRef,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName(NAMESPACE, QName.createValidLocalName("My First Folder")),
                ContentModel.TYPE_FOLDER,
                nodeProperties);
        NodeRef folderRef = assocRef.getChildRef();
        
        // create a file
        nodeProperties.clear();
        nodeProperties.put(ContentModel.PROP_NAME, "My First File");
        assocRef = nodeService.createNode(
                folderRef,
                ContentModel.ASSOC_CONTAINS,
                QName.createQName(NAMESPACE, QName.createValidLocalName("My First File")),
                ContentModel.TYPE_CONTENT,
                nodeProperties);
        NodeRef fileRef = assocRef.getChildRef();
        
        ContentWriter writer = contentService.getWriter(fileRef, ContentModel.PROP_CONTENT, true);
        // the mimetype will up pushed onto the node automatically once the stream closes
        writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
        // store string content as UTF-8
        writer.setEncoding("UTF-8");
        
        // write some content - this API allows streaming and direct loading,
        // but for now we'll just upload a string
        // The writer, being updating, will take care of updating the node once the stream
        // closes.
        String content = "The quick brown fox jumps over the lazy dog";
        writer.putContent(content);
        
        // dump the content to a file
        File file = TempFileProvider.createTempFile("sample", ".txt");
        ContentReader reader = contentService.getReader(fileRef, ContentModel.PROP_CONTENT);
        reader.getContent(file);
        
        // just to demonstrate the node structure, dump it to the file
        String dump = NodeStoreInspector.dumpNodeStore(nodeService, storeRef);
        System.out.println("Node Store: \n" + dump);
        
        // and much, much more ...
    }
}