/*  Copyright (c) 2001, Oracle Corporation. All Rights Reserved. */
package oracle.portal.sample.v2.devguide.prefstore;

import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.Comparator;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import oracle.portal.provider.v2.DefaultPortletDefinition;
import oracle.portal.provider.v2.ProviderInstance;
import oracle.portal.provider.v2.PortletException;
import oracle.portal.provider.v2.preference.PreferenceStore;
import oracle.portal.provider.v2.preference.Preference;
import oracle.portal.provider.v2.preference.PreferenceStoreException;
import oracle.portal.provider.v2.preference.NameValuePreferenceDataObject;
import oracle.portal.provider.v2.security.AccessControlException;

public class GuestBookPortletDefinition extends DefaultPortletDefinition
{
    private static final String GUEST_BOOK_PREF_TYPE = "oracle.portal.sample.v2.guestbook";
    private static final List sGuestBookPrefTypes = 
        Collections.singletonList(GUEST_BOOK_PREF_TYPE);

    private Map mGuestBookInstances = new HashMap();

    public List getGuestBookEntries(ProviderInstance pi)
        throws PortletException
    {
        synchronized (mGuestBookInstances)
        {
            // Load up the entries from the pref store, if they aren't yet in
            // memory
            List guestBookPrefs= (List)mGuestBookInstances.get(pi.getProviderId());
            if(guestBookPrefs == null)
            {
                PreferenceStore prefStore = getPreferenceStore();
                if(prefStore == null)
                {
                    throw new PortletException("PreferenceStore must be defined for this portlet");
                }
                guestBookPrefs = new ArrayList();
                Iterator i;
                try
                {
                    i = prefStore.list(getGuestBookContextPath(pi),
                                       sGuestBookPrefTypes);
                    Preference pref;
                    while(i.hasNext())
                    {
                        pref = (Preference)i.next();
                        pref.setDataClass(NameValuePreferenceDataObject.class);
                        prefStore.read(pref);
                        guestBookPrefs.add(pref);
                    }

                }
                catch (PreferenceStoreException pse)
                {
                    throw new PortletException(pse);
                }

                // Sort the entries in sequential order
                Collections.sort(guestBookPrefs, new Comparator ()
                    {
                        public int compare(Object o1, Object o2)
                        {
                            String name1 = ((Preference)o1).getName();
                            String name2 = ((Preference)o2).getName();
                            return name1.compareTo(name2);
                        }
                    });

                mGuestBookInstances.put(pi.getProviderId(), guestBookPrefs);
            } // end if guestBookPrefs == null
            return guestBookPrefs;
        } // end synchronized
    }

    public void addGuestBookEntry(ProviderInstance pi, NameValuePreferenceDataObject data)
        throws PortletException
    {
        List guestBookPrefs = getGuestBookEntries(pi);            

        PreferenceStore prefStore = getPreferenceStore();
        if(prefStore == null)
        {
            throw new PortletException("PreferenceStore must be defined for this portlet");
        }

        try
        {
            synchronized (guestBookPrefs)
            {
                Preference pref = new Preference(getGuestBookContextPath(pi),
                                                 String.valueOf(guestBookPrefs.size()),
                                                 GUEST_BOOK_PREF_TYPE,
                                                 data);
                guestBookPrefs.add(pref);
                prefStore.write(pref, false);
            }
        }
        catch(PreferenceStoreException pse)
        {
            throw new PortletException(pse);
        }
    }

    public void deregister(ProviderInstance pi)
        throws IOException, AccessControlException
    {
        super.deregister(pi);
        PreferenceStore prefStore = getPreferenceStore();
        if(prefStore != null)
        {
            synchronized (mGuestBookInstances)
            {
                try
                {
                    prefStore.destroy(getGuestBookContextPath(pi),
                                      sGuestBookPrefTypes);
                }
                catch (PreferenceStoreException pse)
                {
                    throw new IOException(pse.toString());
                }
                mGuestBookInstances.remove(pi.getProviderId());
            }
        }
    }

    protected String getGuestBookContextPath(ProviderInstance pi)
    {
        return pi.getProviderId() + 
            PreferenceStore.PATH_SEPARATOR_CHAR +
            getId();
    }

}

