head	1.23;
access;
symbols
	TIGRIS_1_1_0RC2:1.14.6.5
	TIGRIS_1_1_0RC1:1.14.6.5
	TIGRIS_1_1:1.14.6.5.0.2
	TIGRIS_1_0_8:1.14.6.5
	TIGRIS_1_0_8RC3:1.14.6.5
	TIGRIS_1_0_8RC2:1.14.6.5
	TIGRIS_1_0_8RC1:1.14.6.4
	TIGRIS_1_0_7:1.14.6.4
	TIGRIS_1_0_7RC3:1.14.6.4
	TIGRIS_1_0_7RC2:1.14.6.3
	TIGRIS_1_0_7RC1:1.14.6.3
	TIGRIS_1_0_6:1.14.6.3
	TIGRIS_1_0_6RC5:1.14.6.3
	TIGRIS_1_0_6RC4:1.14.6.3
	TIGRIS_1_0_6RC3:1.14.6.3
	TIGRIS_1_0_6RC2:1.14.6.3
	TIGRIS_1_0_6RC1:1.14.6.3
	TIGRIS_1_0_5:1.14.6.2
	TIGRIS_1_0_5RC6:1.14.6.2
	TIGRIS_1_0_5RC5:1.14.6.2
	TIGRIS_1_0_5RC4:1.14.6.2
	TIGRIS_1_0_5RC3:1.14.6.2
	TIGRIS_1_0_5RC2:1.14.6.2
	TIGRIS_1_0_5RC1:1.14.6.2
	TIGRIS_1_0_4:1.14.6.2
	TIGRIS_1_0_3:1.14.6.2
	TIGRIS_1_0_2:1.14.6.1
	TIGRIS_1_0_1:1.14.6.1
	TIGRIS_1_0:1.14.0.6
	TIGRIS_1_0_0:1.14
	TIGRIS_1_0_0_RC1:1.14.0.2
	dlr:1.1.1
	HELM_PEER_PORT_BRANCH:1.1.1.1;
locks; strict;
comment	@# @;


1.23
date	2001.08.11.09.08.03;	author dlr;	state Exp;
branches;
next	1.22;

1.22
date	2001.08.01.06.36.41;	author edk;	state Exp;
branches;
next	1.21;

1.21
date	2001.07.31.21.29.42;	author edk;	state Exp;
branches;
next	1.20;

1.20
date	2001.07.29.23.11.33;	author edk;	state Exp;
branches;
next	1.19;

1.19
date	2001.07.23.20.18.50;	author dlr;	state Exp;
branches;
next	1.18;

1.18
date	2001.07.19.18.42.22;	author dlr;	state Exp;
branches;
next	1.17;

1.17
date	2001.07.13.02.13.10;	author edk;	state Exp;
branches;
next	1.16;

1.16
date	2001.07.03.19.22.31;	author edk;	state Exp;
branches;
next	1.15;

1.15
date	2001.04.26.00.15.58;	author dlr;	state Exp;
branches;
next	1.14;

1.14
date	2001.03.27.09.29.13;	author edk;	state Exp;
branches
	1.14.6.1;
next	1.13;

1.13
date	2001.03.10.03.52.04;	author edk;	state Exp;
branches;
next	1.12;

1.12
date	2001.03.08.03.30.42;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2001.03.07.17.33.44;	author edk;	state Exp;
branches;
next	1.10;

1.10
date	2001.03.07.01.53.22;	author lucas;	state Exp;
branches;
next	1.9;

1.9
date	2001.03.02.10.22.58;	author edk;	state Exp;
branches;
next	1.8;

1.8
date	2001.03.02.10.16.00;	author edk;	state Exp;
branches;
next	1.7;

1.7
date	2001.03.02.09.05.07;	author edk;	state Exp;
branches;
next	1.6;

1.6
date	2001.03.02.07.32.00;	author edk;	state Exp;
branches;
next	1.5;

1.5
date	2001.03.01.19.30.01;	author edk;	state Exp;
branches;
next	1.4;

1.4
date	2001.02.28.00.14.18;	author ms;	state Exp;
branches;
next	1.3;

1.3
date	2001.02.24.03.59.53;	author dlr;	state Exp;
branches;
next	1.2;

1.2
date	2001.02.21.03.02.22;	author edk;	state Exp;
branches;
next	1.1;

1.1
date	2001.01.28.01.18.22;	author dlr;	state dead;
branches
	1.1.1.1
	1.1.2.1;
next	;

1.1.1.1
date	2001.02.21.00.32.56;	author dlr;	state Exp;
branches;
next	;

1.1.2.1
date	2001.01.28.01.18.22;	author dlr;	state Exp;
branches;
next	1.1.2.2;

1.1.2.2
date	2001.02.10.21.16.21;	author dlr;	state Exp;
branches;
next	1.1.2.3;

1.1.2.3
date	2001.02.10.22.07.10;	author dlr;	state Exp;
branches;
next	1.1.2.4;

1.1.2.4
date	2001.02.10.22.32.05;	author dlr;	state Exp;
branches;
next	1.1.2.5;

1.1.2.5
date	2001.02.12.16.24.32;	author leonardr;	state Exp;
branches;
next	1.1.2.6;

1.1.2.6
date	2001.02.13.00.03.57;	author dlr;	state Exp;
branches;
next	1.1.2.7;

1.1.2.7
date	2001.02.13.00.17.33;	author dlr;	state Exp;
branches;
next	1.1.2.8;

1.1.2.8
date	2001.02.13.00.37.48;	author dlr;	state Exp;
branches;
next	1.1.2.9;

1.1.2.9
date	2001.02.13.02.14.16;	author dlr;	state Exp;
branches;
next	1.1.2.10;

1.1.2.10
date	2001.02.13.03.57.21;	author dlr;	state Exp;
branches;
next	1.1.2.11;

1.1.2.11
date	2001.02.13.18.50.41;	author dlr;	state Exp;
branches;
next	1.1.2.12;

1.1.2.12
date	2001.02.13.20.27.39;	author dlr;	state Exp;
branches;
next	1.1.2.13;

1.1.2.13
date	2001.02.16.03.01.27;	author dlr;	state Exp;
branches;
next	1.1.2.14;

1.1.2.14
date	2001.02.17.20.34.50;	author edk;	state Exp;
branches;
next	1.1.2.15;

1.1.2.15
date	2001.02.18.08.41.28;	author dlr;	state Exp;
branches;
next	1.1.2.16;

1.1.2.16
date	2001.02.18.09.16.30;	author dlr;	state Exp;
branches;
next	1.1.2.17;

1.1.2.17
date	2001.02.20.04.32.47;	author dlr;	state Exp;
branches;
next	1.1.2.18;

1.1.2.18
date	2001.02.20.09.49.20;	author edk;	state Exp;
branches;
next	1.1.2.19;

1.1.2.19
date	2001.02.20.13.40.14;	author edk;	state Exp;
branches;
next	1.1.2.20;

1.1.2.20
date	2001.02.20.18.10.23;	author dlr;	state Exp;
branches;
next	;

1.14.6.1
date	2001.04.17.22.36.28;	author edk;	state Exp;
branches;
next	1.14.6.2;

1.14.6.2
date	2001.04.25.23.48.39;	author dlr;	state Exp;
branches;
next	1.14.6.3;

1.14.6.3
date	2001.06.07.05.06.40;	author edk;	state Exp;
branches;
next	1.14.6.4;

1.14.6.4
date	2001.07.03.18.54.08;	author edk;	state Exp;
branches;
next	1.14.6.5;

1.14.6.5
date	2001.07.13.02.11.45;	author edk;	state Exp;
branches;
next	;


desc
@@


1.23
log
@Upgrading to Turbine 3.0-dev, Fulcrum 1.0, and Torque 1.0.
@
text
@package org.tigris.helm.om;

import java.math.BigDecimal;
import java.util.*;

import org.apache.commons.util.exception.NestableException;

import org.apache.torque.om.NumberKey;
import org.apache.torque.util.Criteria;

import org.tigris.anzu.client.MailingListSpec;

import org.tigris.helm.*;
import org.tigris.helm.om.*;
import org.tigris.helm.security.*;
import org.tigris.helm.tool.DBFlag;
import org.tigris.helm.tool.HelmProperties;
import org.apache.turbine.util.Log;

/**
 * Mailing list business rules.
 *
 * @@author <a href="mailto:elicia@@collab.net">Elicia David</a>
 * @@author <a href="mailto:edk@@collab.net">Ed Korthof</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@version $Id: MailingList.java,v 1.22 2001/08/01 06:36:41 edk Exp $
 *
 * MailingList objects correspond to mailing lists, and are used to modify
 * the settings for given mailing lists, manage the subscription list,
 * and so on.
 *
 * The term group is used to describe the different lists of email addresses
 * which may be associated with a given mailing list; some examples include:
 * normal subscribers, moderators, digest subscribers, and (for ezmlm) the
 * allow list.
 */
public class MailingList extends BaseMailingList
{
    /**
     * Where should archive e-mail go
     */
    protected static String mailArchiveHost = null;

    /**
     * If debugging is turned on
     */
    public static boolean DEBUG = false;

    /**
     * The prefix required for lists and addresses.
     */
    protected static String mailPrefix = null;

    final static String MAIL_PREFIX_KEY = "mailPrefix";
    final static String MAIL_ARCHIVE_HOST_KEY = "mailArchiveHost";

    static
    {
        try
        {
            HelmProperties properties = HelmProperties.getInstance();
            if (properties == null)
            {
                throw new NullPointerException( "HelmProperties is null" );
            }

            mailArchiveHost = properties.getProperty(MAIL_ARCHIVE_HOST_KEY);
            if (mailArchiveHost == null)
            {
                Log.error(MAIL_ARCHIVE_HOST_KEY + " missing; archiver " +
                          "addresses will not be subscribed automatically");
            }

            mailPrefix = properties.getProperty(MAIL_PREFIX_KEY);
            if (mailPrefix == null)
            {
                mailPrefix = "";
            }
        }
        catch (Exception e)
        {
            Log.error("Unable to read application properties", e);
        }
    }

    /**
     * Groups correspond to different lists of email addresses associated
     * with a single mailing list.
     */

    /**
     * Normal subscribers
     */
    public static String SUBSCRIBER_GROUP = "";

    /**
     * Moderators
     */
    public static String MODERATOR_GROUP = "mod";

    /**
     * Digest subscribers
     */
    public static String DIGEST_GROUP = "digest";

    /**
     * The allow list
     */
    public static String ALLOW_GROUP = "allow";

    private MailingListSpec mailingListSpec = null;
    private boolean exists = true;
    private String owner = null;

    /**
     * Has there been an error?  This is so we don't throw an error
     * on setDescription/setIsPrivate -- we throw it later, on save. 
     * (Is that a good thing?  It means error handling can be concentrated,
     * at least.)
     */
    protected Exception error = null;

    /**
     * Adds a new mailing list to the specified project.
     *
     * @@param acl      The ACL to check for permission.
     * @@param project  The project to add the mailing list to.
     * @@param listName The name of the list to add.
     * @@param descrip  The list description, or <code>null</code> for none.
     * @@param type     The type of mailing list to add, or
     *                 <code>null</code> for unspecified.
     * @@return         The mailing list just added.
     */
    public static MailingList add(AccessControlList acl, Project project,
                                  String listName, String descrip, String type)
        throws ACLException, Exception
    {
        if (DEBUG) {
            Log.debug("in MailingList.add, listName: " + listName +
                ", description: " + descrip + ", type : " + type);
        }
        acl.assertPermission("Mailing List - Add", project);
        MailingList ml = new MailingList();
        ml.mailingListSpec = null;
        ml.error = null;
        ml.setProject(project);
        ml.setListName(listName);
        if (descrip == null) {
            descrip = "";
        }
        ml.setDescription(descrip);
        if (type != null) {
            ml.setType(type);
        }
        ml.exists = false;
        // owner is not used in this context (it's in creating new lists):
        ml.owner = null;
        // we don't save here, unlike other BOs, 'cause save is a separate
        // action, and must be called explicitly
        return ml;
    }


    /**
     * Constructor for an existing mailing list.  This is package level
     * visibility, since it should not be used by code outside the om
     * package.  The particular arguments are designed for efficiency
     * when working w/ Torque ...
     */
    MailingList(BigDecimal mailingListId, BigDecimal projectId,
            String listName, String type, String isPrivate, String description)
        throws Exception
    {
        super();
        super.setMailinglistId(new NumberKey(mailingListId));
        super.setProjectId(new NumberKey(projectId));
        super.setListName(listName);
        super.setType(type);
        super.setIsPrivate(isPrivate);
        super.setDescription(description);
        setModified(false);
        setNew(false);
    }

    /**
     * No args constructor, for use where needed
     */
    MailingList() {
        // class initializers -- up above -- handle this
    }

    /**
     * This setting is used for the description in certain displays.
     */
    public void setDescription(String value)
    {
        super.setDescription(value);
        try {
            setStringOption("description", value);
        }
        catch (Exception e) {
            Log.error(e);
            Log.warn("unable to set description");
            error = e;
        }
    }

    /**
     * This setting toggles whether or not the list is private --
     * which affects subscription and viewing the archive.
     */
    public void setPrivate(boolean value)
    {
        super.setIsPrivate(DBFlag.flagValueOf(value));
        try {
            setBooleanOption("sub_moderation",
                    value ? Boolean.TRUE : Boolean.FALSE);
        }
        catch (Exception e) {
            Log.error(e);
            Log.warn("unable to setIsPrivate");
            error = e;
        }
    }

    /**
     * This returns true if the list is private, and false otherwise.
     */
    public boolean isPrivate()
    {
        return DBFlag.booleanValueOf(getIsPrivate());
    }

    /**
     * This method is used to connect with the Anzu classes.  It does
     * implicitly connect to the remote anzu server.  It uses reflection
     * to avoid requiring Anzu to compile.
     * 
     * @@return Whether or not the connection attempt was successful.
     */
    public boolean connect()
    {
        if (mailingListSpec == null) {
            try {
                Project p = getProject();
                mailingListSpec = new MailingListSpec 
                    (p.getDomain().getName(), p.getName(), getListName());
            }
            catch (Exception e) {
                Log.warn("Error trying to connect to Anzu", e);
                mailingListSpec = null;
                return false;
            }
        }
        return true;
    }

    /**
     * This method will either create or update the existing list.
     */
    public void save(AccessControlList acl)
        throws ACLException, AlreadyExists, NestableException, Exception
    {
        if (anzuDisabled()) {
            return;
        }
        if (error != null) {
            Log.warn("stored error prevents MailingList.save");
            throw new NestableException("MailingList error before save", error);
        }
        
        checkPermission(acl, "Add");

        if (owner != null) {
            setStringOption("owner", owner);
        }
        if (exists) {
            update();
        }
        else {
            create();
        }
        if (owner != null) {
            try {
                List autoSubscribe = new ArrayList();
                autoSubscribe.add(owner);
                subscribe(autoSubscribe, MODERATOR_GROUP);
                subscribe(autoSubscribe, ALLOW_GROUP);
            }
            catch (Exception e) {
                Log.error("Unable to add owner to mod/allow: " + owner);
            }
        }
    }

    /**
     * Updates an existing list
     */
    private void update()
        throws NestableException
    {
        try {
            super.save();
            mailingListSpec.update();
        }
        catch (Exception e) {
            Log.error(e);
            throw new NestableException("unable to update/save MailingList", e);
        }
    }

    /**
     * Creates the the list.
     */
    private void create()
        throws AlreadyExists, NestableException, Exception
    {
        MailingListPeer.doInsert(this);

        try {
            mailingListSpec.create();
        }
        catch (Exception e) {
            try {
                MailingListPeer.doDelete(this);
            }
            catch (Exception rollbackFailed) {
                throw new NestableException
                    ("Error trying to roll back addition of mailing " +
                     "list to database after Anzu error; the database " +
                     "may not be in a consistent state!", rollbackFailed);
            }
            throw new NestableException("Anzu failed to create mailing list", e);
        }

        try {
            handleArchiveAddition();
        }
        catch (Exception e)
        {
            try {
                MailingListPeer.doDelete(this);
            }
            catch (Exception rollbackFailed) {
                throw new NestableException
                    ("Error trying to roll back addition of mailing " +
                     "list to database after Anzu error; the database " +
                     "may not be in a consistent state!", rollbackFailed);
            }
            try {
                mailingListSpec.delete();
            }
            catch (Exception deleteFailed) {
                // probably the mailing list spec wasn't created successfully
                Log.error(deleteFailed);
            }
            throw new NestableException("Anzu failed to create mailing list", e);
        }

        exists = true;
    }

    /**
     * Delets this mailing list.
     */
    public void delete(AccessControlList acl)
        throws ACLException, Exception
    {
        checkPermission(acl, "Delete");
        delete();
    }

    protected void handleArchiveAddition()
        throws Exception
    {
        Log.debug("Trying to add archiver to mailing list");
        if (mailArchiveHost != null) {
            List addrs = new ArrayList();
            addrs.add(getArchiveAddress());
            mailingListSpec.subscribe(addrs, SUBSCRIBER_GROUP);
            // eyebrowseAddList();
        }
        else {
            Log.warn("Not adding archiver to list " + getListName() +
                     " in project " + getProject().getName());
        }
    }

    /**
     * Extends the functionality of the base class to also invoke the
     * dynamic <code>MLS_setListType</code> method and to set list
     * options.
     */
    public void setType(String type)
    {
        super.setType(type);
        try {
            if (anzuDisabled()) return;
            try {
                mailingListSpec.setListType(type);
            }
            catch (Exception e) {
                throw new NestableException("Anzu error", e);
            }
        }
        catch (Exception e) {
            Log.error("Connection to Anzu server failed: " +
                      e.getMessage(), e);
            return;
        }
    }

    /**
     * Sets the owner of this mailing list.  Also sets list options.
     *
     * @@param owner The email address for the owner of the list.
     */
    public void setOwner(String owner)
        throws NestableException, Exception
    {
        this.owner = owner;
        if (exists) {
            setStringOption("owner", owner);
        }
    }

    /**
     * Returns whether the list has been created yet (MailingList objects
     * must be explicitly created before they exist in the file system/
     * permanently).
     */
    public boolean exists()
    {
        return exists;
    }

    /**
     * This is mostly for internal use : it provides the archive address
     * which needs to be subscribed for archiving to work correctly.
     *
     * @@return A String which contains the email address for archiving this
     * list
     */
    public String getArchiveAddress()
        throws Exception
    {
        String addr = null;
        if (mailArchiveHost != null) {
            Project p = getProject();
            addr = mailPrefix + "archive=mail-" + p.getName() + '=' +
                getListName() + '=' + p.getDomain().getName() + '@@' +
                mailArchiveHost;
        }
        else {
            Log.warn("Unable to determine mail archive address, since " +
                     "mail_archive_host property was not set");
        }
        return addr;
    }

    /**
     * This shouldn't be used outside this class anymore -- getAddress
     * is prefered for client code.  This is used by templates to get the
     * appropriate list prefix.  Right now, all it handles is the
     * mail prefix.
     *
     * TODO : handle vhosting.  For vhosted lists, it should be getName() ;
     * but for non-vhosted list, it'll be project-getName().
     */
    public String getEmailPrefix()
    {
        return mailPrefix + getListName();
    }

    /**
     * If used w/ a null argument or an empty String, it will return
     * the address to post to this list.  Otherwise, it'll return the
     * address for the given command.
     *
     * @@param command The command to run, or <code>null</code> for the
     * posting address.
     * @@return        An e-mail address.
     */
    public String getAddress(String command)
        throws Exception
    {
        StringBuffer addr = new StringBuffer(getEmailPrefix());
        if (command != null && !command.equals("")) {
            addr.append('-').append(command);
        }
        return addr.append('@@').append(getEmailDomain()).toString();
    }

    /**
     * Returns the email domain of the list (i.e. <code>foo.com
     * TODO : handle vhosting
     */
    protected final String getEmailDomain()
        throws Exception
    {
        Project project = getProject();
        String projectName = project.getName();
        if (projectName.equals(ProjectPeer.DEFAULT_PROJECT_NAME))
            return project.getDomain().getName();
        else 
            return project.getName() + '.' + project.getDomain().getName();
    }

    /**
     * Internal delete, with no permission checking (NC).
     */
    protected void delete()
        throws Exception
    {
        if (anzuDisabled()) return;
        String listName = getAddress(null);
        try {
            MailingListPeer.doDelete(this);
        }
        catch (Exception e) {
            throw new NestableException("MailingListPeer.doDelete failed: " +
                                       "The database may be in an invalid state", e);
        }
        try {
            mailingListSpec.delete();
        }
        catch (Exception e) {
            throw new NestableException("Anzu delete mailing list failed: " +
                                       "The database may be in an invalid state", e);
        }
    }

    /**
     * Checks the provided ACL for the permission indicated by the mailing
     * list operation.
     */
    private final void checkPermission(AccessControlList acl, String operation)
        throws ACLException, Exception
    {
        acl.assertPermission("Mailing List - " + operation, getProject());
    }

    /**
     * Checks whether Anzu is disabled, and whether the Anzu server can be
     * connected to.
     */
    private boolean anzuDisabled()
        throws Exception
    {
        if (!connect()) {
            Log.error("Unable to connect to Anzu server; bailing out");
            throw new Exception("Anzu is installed but the server " +
                                "is not running");
        }
        else {
            return false;
        }
    }

    /**
     * Returns the available mailing list types.
     *
     * @@return Available list types.
     */
    public List getListTypes()
        throws NestableException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return mailingListSpec.getListTypes();
        }
        catch (Exception e) {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Get the current options for this list
     *
     * @@return A List of org.tigris.anzu.list.ListOption objects
     */
    public List getOptionsList()
        throws NestableException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return mailingListSpec.getOptionsList();
        }
        catch (Exception e) {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Get the allowed list of options
     *
     * @@return A List of org.tigris.anzu.list.OptionSpec objects
     */
    public List getOptionTypes()
        throws NestableException, Exception
    {
        if (anzuDisabled()) return null;

        return mailingListSpec.getOptionTypes();
    }

    /**
     * Return the current options for this list in a Map format
     *
     * @@return A Map whose keys are Strings and whose values are
     * org.tigris.anzu.list.ListOption objects
     */
    public Map getOptionsMap()
        throws NestableException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return mailingListSpec.getOptionsMap();
        }
        catch (Exception e) {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Gets a <code>Boolean</code> parameter for a dynamically invoked
     * method.
     *
     * @@param option Name of the parameter to get the value of.
     * @@return       Parameter value.
     */
    public Boolean getBooleanOption(String option)
        throws NestableException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return mailingListSpec.getBooleanOption(option);
        }
        catch (Exception e) {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Gets a <code>String</code> parameter for a dynamically invoked
     * method.
     *
     * @@param option Name of the parameter to get the value of.
     * @@return       Parameter value.
     */
    public String getStringOption(String option)
        throws NestableException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return mailingListSpec.getStringOption(option);
        }
        catch (Exception e) {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Sets a <code>Boolean</code> parameter for a dynamically invoked
     * method.
     */
    public void setBooleanOption(String option, Boolean value)
        throws NestableException, Exception
    {
        if (anzuDisabled()) return;
        try {
            mailingListSpec.setBooleanOption(option, value);
        }
        catch (Exception e) {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Sets a <code>String</code> parameter for a dynamically invoked
     * method.
     */
    public void setStringOption(String option, String value)
        throws NestableException, Exception
    {
        if (anzuDisabled()) return;
        try 
        {
            mailingListSpec.setStringOption(option, value);
        }
        catch (Exception e)
        {
            throw new NestableException("Anzu error", e);
        }
    }

    /**
     * Lists the subscribers in a group on the mailing list
     *
     * @@param group The group (use the public _GROUP symbols in this class)
     * @@return a List of email addresses constituting the subscriber list
     */
    public List listMembers(String group) throws NestableException, Exception
    {   
        if (anzuDisabled()) return null;
   
        return mailingListSpec.listMembers(group);
    }

    /**
     * Subscribes a list of email addresses to a group.
     *
     * @@param addrs The email addresses to subscribe.
     * @@param group The group (use the public _GROUP symbols in this class)
     */
    public void subscribe(List addrs, String group)
        throws NestableException, Exception
    {
        if (anzuDisabled()) return;
        try {
            mailingListSpec.subscribe(addrs, group);
        }
        catch (Exception e) {
            throw new NestableException("Unable to use Anzu subscribe", e);
        }
    }

    /**
     * Returns true iff this list can be viewed by the permissions
     * of the given ACL.
     *
     * @@param acl The ACL to check for permission.
     */
    public boolean isViewableBy(AccessControlList acl)
        throws Exception
    {   
        boolean ok = true;
        if (isPrivate())
        {
            Log.warn("private mailing list " + this);
            if (!acl.hasPermission("Private Mailing List - View", getProject()))
            {
                ok = false;
            }
        }
        else
        {
            Log.warn("public mailing list " + this);
            if (!acl.hasPermission("Mailing List - View", getProject()))
            {
                ok = false;
            }
        }
        return ok;
    }

    /**
     * Unsubscribes a list of email addresses from a group.
     *
     * @@param addrs The email addresses to unsubscribe.
     * @@param group The group (use the public _GROUP symbols in this class)
     */
    public void unsubscribe(List addrs, String group) 
        throws NestableException, Exception
    {
        if (anzuDisabled()) return;
        try {
            mailingListSpec.unsubscribe(addrs, group);
        }
        catch (Exception e) {
            throw new NestableException("Unable to use Anzu unsubscribe", e);
        }
    }
}
@


1.22
log
@avoid knowledge of the persistence layer in the business object
(the import wasn't needed anyway)
@
text
@d3 1
d6 1
a6 5
import org.apache.turbine.om.*;
import org.apache.turbine.util.*;
import org.apache.turbine.util.db.Criteria;

import java.math.BigDecimal;
d8 2
a9 1
import org.tigris.helm.tool.HelmProperties;
d18 1
d26 1
a26 1
 * @@version $Id: MailingList.java,v 1.21 2001/07/31 21:29:42 edk Exp $
d262 1
a262 1
        throws ACLException, AlreadyExists, TurbineException, Exception
d269 1
a269 1
            throw new TurbineException("MailingList error before save", error);
d300 1
a300 1
        throws TurbineException
d308 1
a308 1
            throw new TurbineException("unable to update/save MailingList", e);
d316 1
a316 1
        throws AlreadyExists, TurbineException, Exception
d328 1
a328 1
                throw new TurbineException
d333 1
a333 1
            throw new TurbineException("Anzu failed to create mailing list", e);
d345 1
a345 1
                throw new TurbineException
d357 1
a357 1
            throw new TurbineException("Anzu failed to create mailing list", e);
d403 1
a403 1
                throw new TurbineException("Anzu error", e);
d419 1
a419 1
        throws TurbineException, Exception
d521 1
a521 1
            throw new TurbineException("MailingListPeer.doDelete failed: " +
d528 1
a528 1
            throw new TurbineException("Anzu delete mailing list failed: " +
d566 1
a566 1
        throws TurbineException, Exception
d573 1
a573 1
            throw new TurbineException("Anzu error", e);
d583 1
a583 1
        throws TurbineException, Exception
d590 1
a590 1
            throw new TurbineException("Anzu error", e);
d600 1
a600 1
        throws TurbineException, Exception
d614 1
a614 1
        throws TurbineException, Exception
d621 1
a621 1
            throw new TurbineException("Anzu error", e);
d633 1
a633 1
        throws TurbineException, Exception
d640 1
a640 1
            throw new TurbineException("Anzu error", e);
d652 1
a652 1
        throws TurbineException, Exception
d659 1
a659 1
            throw new TurbineException("Anzu error", e);
d668 1
a668 1
        throws TurbineException, Exception
d675 1
a675 1
            throw new TurbineException("Anzu error", e);
d684 1
a684 1
        throws TurbineException, Exception
d693 1
a693 1
            throw new TurbineException("Anzu error", e);
d703 1
a703 1
    public List listMembers(String group) throws TurbineException, Exception
d717 1
a717 1
        throws TurbineException, Exception
d724 1
a724 1
            throw new TurbineException("Unable to use Anzu subscribe", e);
d764 1
a764 1
        throws TurbineException, Exception
d771 1
a771 1
            throw new TurbineException("Unable to use Anzu unsubscribe", e);
@


1.21
log
@* support a more efficient (and correct) way to retrieve mailing lists
  than the default row2Object -- port this from the branch
* remove some cruft from MailingList
@
text
@a20 2
import com.workingdogs.village.*;

d27 1
a27 1
 * @@version $Id: MailingList.java,v 1.20 2001/07/29 23:11:33 edk Exp $
@


1.20
log
@change setOwner to take a String, rather than a User; change the
corresponding variable where this can be stored.
@
text
@d9 2
d21 2
d29 1
a29 1
 * @@version $Id: MailingList.java,v 1.19 2001/07/23 20:18:50 dlr Exp $
d166 29
a250 6
                // nasty ugly hack which allows more efficient use of mailing
                // list while dealing with turbine : the first time we
                // connect, we set the list type.  that's so that setType
                // doesn't need to do so itself ... since setType is called
                // implicitly by Torque when it's not really needed.  ditto
                // for setDescription, setIsPrivate
a390 23
/*
RM
    protected void eyebrowseAddList()
        throws Exception
    {
        Log.debug("Trying to add mailing list file with Eyebrowse");
        String listName = getAddress(null);
        {
            Object args[] = { listName, getDescription(),
                              Integer.valueOf(getID()) };
            ELM_addList.invoke(null, args);
        }
        {
            Project p = getProject();
            Object args[] = { listName,
                              HelmProperties.getProperty("SANDBOX") +
                              "/data/eyebrowse/" + p.getDomain().getName() +
                              '/' + p.getName() + '/' + getListName() +
                              "/0mbox" };
            ELM_addListFile.invoke(null, args);
        }
    }
*/
a657 1
        Object args[] = { option };
@


1.19
log
@Clean up of import statements and streamlined initial reading of
properties.
@
text
@d25 1
a25 1
 * @@version $Id: MailingList.java,v 1.18 2001/07/19 18:42:22 dlr Exp $
d112 1
a112 1
    private User owner = null;
d251 1
a251 1
            setStringOption("owner", owner.getEmail());
d262 1
a262 1
                autoSubscribe.add(owner.getEmail());
d267 1
a267 2
                Log.error("Unable to add owner to mod/allow: " +
                          owner.getEmail());
d415 1
a415 1
     * @@param owner The owner of the list.
d417 1
a417 1
    public void setOwner(User owner)
d422 1
a422 1
            setStringOption("owner", owner.getEmail());
@


1.18
log
@Updated in light of the port of Joist JoistProperties class to Helm (as class HelmProperties).
@
text
@d6 1
a6 1
import org.apache.turbine.om.peer.BasePeer;
a7 5
import org.apache.turbine.util.ObjectUtils;
import org.apache.turbine.util.StringUtils;
import org.apache.turbine.util.ParameterParser;
import org.apache.turbine.util.*;
import org.apache.turbine.util.db.pool.DBConnection;
d17 1
d25 1
a25 1
 * @@version $Id: MailingList.java,v 1.17 2001/07/13 02:13:10 edk Exp $
d60 2
a61 3
            org.tigris.helm.tool.HelmProperties properties
                = org.tigris.helm.tool.HelmProperties.getInstance( );
            if( properties == null )
a65 1

d69 2
a70 2
                Log.error(MAIL_ARCHIVE_HOST_KEY + "missing; archiver addresses "
                        + "will not be subscribed automatically");
d81 1
a81 1
            Log.error("unable to read stuff from joist properties", e);
@


1.17
log
@rollback db row insertion when creation fails in anzu (really we should
also give the db a composit pk so that this is even less of an issue)
@
text
@d14 1
a14 1
import org.joist.util.JoistProperties;
d29 1
a29 1
 * @@version $Id: MailingList.java,v 1.16 2001/07/03 19:22:31 edk Exp $
d64 2
a65 2
            org.joist.util.JoistProperties properties
                = org.joist.util.JoistProperties.getInstance( );
d68 1
a68 1
                throw new NullPointerException( "JoistProperties is null" );
d386 1
a386 1
                              JoistProperties.getProperty("SANDBOX") +
@


1.16
log
@don't delete a mailing list which already exists if someone tries to
create it again (d'oh)
@
text
@d29 1
a29 1
 * @@version $Id: MailingList.java,v 1.15 2001/04/26 00:15:58 dlr Exp $
d307 9
a324 7
                mailingListSpec.delete();
            }
            catch (Exception deleteFailed) {
                // probably the mailing list spec wasn't created successfully
                Log.error(deleteFailed);
            }
            try {
d332 7
@


1.15
log
@Minor cleanup that accidently crept into the 1.0 branch.  Might as
well have it here in the HEAD for consistancy as well.
@
text
@d29 1
a29 1
 * @@version $Id: MailingList.java,v 1.14 2001/03/27 09:29:13 edk Exp $
d305 6
d313 2
a314 1
        catch (Exception e) {
@


1.14
log
@* provide mail_prefix, which is required for dev sandboxes to work
  correctly
* rename mail_prefix => mailPrefix and mail_archive_host =>
  mailArchiveHost for consistency w/ other such properties
@
text
@a3 1
//import java.lang.reflect.*;
d18 1
a21 1
import org.tigris.helm.*;
d29 1
a29 1
 * @@version $Id: MailingList.java,v 1.13 2001/03/10 03:52:04 edk Exp $
@


1.14.6.1
log
@change so that it's possible to use a more efficient row2Object when you
select a list of mailing lists: now we avoid calling methods which would
cause unnecessary RMI connections when viewing a list of mailing lists.
@
text
@a3 1
import java.math.BigDecimal;
a22 1
import com.workingdogs.village.*;
d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.14 2001/03/27 09:29:13 edk Exp $
a168 29

    /**
     * Constructor for an existing mailing list.  This is package level
     * visibility, since it should not be used by code outside the om
     * package.  The particular arguments are designed for efficiency
     * when working w/ Torque ...
     */
    MailingList(BigDecimal mailingListId, BigDecimal projectId,
            String listName, String type, String isPrivate, String description)
        throws Exception
    {
        super();
        super.setMailinglistId(new NumberKey(mailingListId));
        super.setProjectId(new NumberKey(projectId));
        super.setListName(listName);
        super.setType(type);
        super.setIsPrivate(isPrivate);
        super.setDescription(description);
        setModified(false);
        setNew(false);
    }

    /**
     * No args constructor, for use where needed
     */
    MailingList() {
        // class initializers -- up above -- handle this
    }

d225 6
@


1.14.6.2
log
@Back ported Joist servlets which have been merged into Helm in the HEAD.
@
text
@d5 1
a19 1
import org.tigris.helm.*;
d23 2
d32 1
a32 1
 * @@version $Id: MailingList.java,v 1.14.6.1 2001/04/17 22:36:28 edk Exp $
@


1.14.6.3
log
@remove debugging lines; and add a call to Project.addMailingLists
which updates the project's internal list of mailing lists.

Project.addMailingLists will call setProject internally -- but I left
in the call to that 'cause I worry that it might be changed, and logically
the setting of the project should be in the mailing list creation function.
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.14.6.2 2001/04/25 23:48:39 dlr Exp $
a151 1
        project.addMailingLists(ml);
d755 1
d763 1
@


1.14.6.4
log
@create may fail if the list already exists (d'oh!) -- don't delete
in that case.
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.14.6.3 2001/06/07 05:06:40 edk Exp $
d330 1
a332 8
            throw new TurbineException("Anzu failed to create mailing list", e);
        }

        try {
            handleArchiveAddition();
        }
        catch (Exception e)
        {
@


1.14.6.5
log
@rollback db row insertion when creation fails in anzu (really we should
also give the db a composit pk so that this is even less of an issue)
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.14.6.4 2001/07/03 18:54:08 edk Exp $
a331 9
            try {
                MailingListPeer.doDelete(this);
            }
            catch (Exception rollbackFailed) {
                throw new TurbineException
                    ("Error trying to roll back addition of mailing " +
                     "list to database after Anzu error; the database " +
                     "may not be in a consistent state!", rollbackFailed);
            }
d341 7
a354 7
            }
            try {
                mailingListSpec.delete();
            }
            catch (Exception deleteFailed) {
                // probably the mailing list spec wasn't created successfully
                Log.error(deleteFailed);
@


1.13
log
@* implement MailingList.isViewableBy(AccessControlList)
* use that to filter the list of mailing lists for a project based on
  viewer
* cleanup/document TODOs
* call AnzuTask.deleteProject in Project when a project is deleted
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.12 2001/03/08 03:30:42 dlr Exp $
d58 3
a71 3
            // this is silly ... but follows the pattern. 
            final String MAIL_PREFIX_KEY = "mail_prefix";
            final String MAIL_ARCHIVE_HOST_KEY = "mail_archive_host";
d73 1
a73 1
            mailArchiveHost = properties.getProperty("mail_archive_host");
d76 2
a77 2
                Log.error("mail_archive_host missing; archiver addresses " +
                        "will not be subscribed automatically");
d80 1
a80 1
            mailPrefix = properties.getProperty("mail_prefix");
d225 6
@


1.12
log
@Pushed getID() method into base class as a final method.
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.11 2001/03/07 17:33:44 edk Exp $
d423 5
a427 1
     * TODO: Document.
d481 1
d563 1
a563 1
     * TODO: Document.
d565 1
a565 1
     * @@return TODO
d580 1
a580 1
     * TODO: Document.
d582 1
a582 1
     * @@return TODO
d593 1
a593 1
     * TODO: Document.
d595 2
a596 1
     * @@return TODO
d712 29
@


1.11
log
@* changes to use the private toggle, which will replace -private list types
* fix a bug in MailingList : update wasn't implemented (d'oh)
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.10 2001/03/07 01:53:22 lucas Exp $
a419 8
    }

    /**
     * Gets the primary database key of this mailing list.
     */
    public final String getID()
    {
        return getPrimaryKey().toString();
@


1.10
log
@Corrected regex madness for Torque upgrade.  -dlr
@
text
@d21 1
d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.9 2001/03/02 10:22:58 edk Exp $
d122 8
d151 1
d170 42
d241 8
a248 1
        if (anzuDisabled()) return;
d278 1
a278 1
        throws AlreadyExists, TurbineException, Exception
d280 8
a287 1
        //TODO : implement this
@


1.9
log
@this *really* annoying bug was caused by a code reorganization which lead
to initializing an instance variable to null at a point which was too late.
the instance variable had already been initialized and modified by that
point; those modifications were lost.
@
text
@d19 1
a19 2
import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.base.*;
d29 1
a29 1
 * @@version $Id: MailingList.java,v 1.8 2001/03/02 10:16:00 edk Exp $
@


1.8
log
@there's no longer any need to set the mail_prefix option; anzu handles
it on its own.  the only use left -- for the archiver address -- should
move into anzu as well.
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.7 2001/03/02 09:05:07 edk Exp $
d142 1
a151 1
        ml.mailingListSpec = null;
@


1.7
log
@improve accuracy of javadocs
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.6 2001/03/02 07:32:00 edk Exp $
a173 1
                setStringOption("mail_prefix", mailPrefix);
a323 6
            }
            // This is part of the business logic -- it belongs here.  It
            // needs to be called every time setType is because setType
            // will overwrite all the current options ...
            if (mailPrefix != null) {
                setStringOption("mail_prefix", mailPrefix);
@


1.6
log
@* remove a constructor which will not produce a valid list (no list should
  ever be created without a type or a description)
* better debugging info
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.5 2001/03/01 19:30:01 edk Exp $
d393 7
a399 3
     * This is used by templates to get the appropriate list prefix.
     * For vhosted lists, that's getName() ; but for non-vhosted list,
     * it'll be project-getName().
d411 2
a412 1
     * @@param command The command to run, or <code>null</code> for the posting address.
@


1.5
log
@* nuke bad logic in the add function, which was saving and saying that
  the mailing list exist.  save must be called explicitly.
* actually add the archive addresses to the mailing list when it's created
  (probably this logic should move into anzu now)
* use SUBSCRIBER_GROUP rather than litteral " " (which should have been "")
  for subscribing the archiver address; ditto for use of "mod" and "allow"
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.4 2001/02/28 00:14:18 ms Exp $
d49 5
a126 15
     * @@return         The mailing list just added.
     */
    public static MailingList add(AccessControlList acl, Project project,
                                  String listName)
        throws ACLException, Exception
    {
        return add(acl, project, listName, null, null);
    }

    /**
     * Adds a new mailing list to the specified project.
     *
     * @@param acl      The ACL to check for permission.
     * @@param project  The project to add the mailing list to.
     * @@param listName The name of the list to add.
d136 4
@


1.4
log
@Removed the reflection to anzu mailingListSpec in favor of direct access
to anzu.
@
text
@d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.3 2001/02/24 03:59:53 dlr Exp $
a156 1
        ml.save();
d158 1
a158 1
        ml.exists = true;
d161 2
d213 2
a214 2
                subscribe(autoSubscribe, "mod");
                subscribe(autoSubscribe, "allow");
d242 1
d246 7
d284 1
a284 1
            mailingListSpec.subscribe(addrs, " ");
@


1.3
log
@Sync'd with latest Turbine changes.  Mostly this consists of the use of the new SimpleKey class to handle primary database keys.
@
text
@d4 1
a4 1
import java.lang.reflect.*;
d17 2
d30 1
a30 1
 * @@version $Id: MailingList.java,v 1.2 2001/02/21 03:02:22 edk Exp $
d112 1
a112 24
    protected static Constructor mailingListSpecConstructor = null;
    protected static Method MLS_create = null; // void
    protected static Method MLS_update = null; // void
    protected static Method MLS_delete = null; // void
    protected static Method MLS_setListType = null; //void
    protected static Method MLS_setBooleanOption = null; //void
    protected static Method MLS_setStringOption = null; //void
    protected static Method MLS_getBooleanOption = null; //void
    protected static Method MLS_getStringOption = null; //void
    protected static Method MLS_getListTypes = null; //List
    protected static Method MLS_getOptionTypes = null; //List
    protected static Method MLS_getOptionsMap = null; //List
    protected static Method MLS_getOptionsList = null; //List
    protected static Method MLS_subscribe = null; //void
    protected static Method MLS_unsubscribe = null; //void
    protected static Method MLS_listMembers = null; //List
    protected static Method ELM_deleteList = null; //void
    protected static Method ELM_addList = null; // void
    protected static Method ELM_addListFile = null; // void

    private static boolean anzu = false;
    private static boolean eyebrowse = false;

    private Object mailingListSpec = null;
a115 118
    static
    {
        try {
            Class MLSClass =
                Class.forName("org.tigris.anzu.client.MailingListSpec");
            {
                Class argTypes[] = {
                        String.class, String.class, String.class
                };
                mailingListSpecConstructor =
                    MLSClass.getConstructor(argTypes);
            }

            {
                Class argTypes[] = {};
                MLS_create = MLSClass.getDeclaredMethod("create", argTypes);
                MLS_update = MLSClass.getDeclaredMethod("update", argTypes);
                MLS_delete = MLSClass.getDeclaredMethod("delete", argTypes);
                MLS_getOptionsList =
                    MLSClass.getDeclaredMethod("getOptionsList", argTypes);
                MLS_getOptionsMap =
                    MLSClass.getDeclaredMethod("getOptionsMap", argTypes);
                MLS_getOptionTypes =
                    MLSClass.getDeclaredMethod("getOptionTypes", argTypes);
                MLS_getListTypes =
                    MLSClass.getDeclaredMethod("getListTypes", argTypes);
            }

            {
                Class argTypes[] = {
                    List.class, String.class
                };
                MLS_subscribe =
                    MLSClass.getDeclaredMethod("subscribe", argTypes);
                MLS_unsubscribe =
                    MLSClass.getDeclaredMethod("unsubscribe", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class
                };
                MLS_setListType =
                    MLSClass.getDeclaredMethod("setListType", argTypes);
                MLS_getBooleanOption =
                    MLSClass.getDeclaredMethod("getBooleanOption", argTypes);
                MLS_getStringOption =
                    MLSClass.getDeclaredMethod("getStringOption", argTypes);
                MLS_listMembers =
                    MLSClass.getDeclaredMethod("listMembers", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, String.class
                };
                MLS_setStringOption =
                    MLSClass.getDeclaredMethod("setStringOption", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, Boolean.class
                };
                MLS_setBooleanOption =
                    MLSClass.getDeclaredMethod("setBooleanOption", argTypes);
            }
            anzu = true;

            Class ELMClass =
                Class.forName("org.tigris.eyebrowse.ListMaint");
            {
                Class argTypes[] = {
                    String.class
                };
                ELM_deleteList =
                    ELMClass.getDeclaredMethod("deleteList", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, String.class
                };
                ELM_addListFile = // String list name, String filename
                    ELMClass.getDeclaredMethod("addListFile", argTypes);
            }
            {
                Class argTypes[] = {
                    String.class, String.class, Integer.class
                };
                ELM_addList = // String listName, String desc, String ID
                    ELMClass.getDeclaredMethod("addList", argTypes);
            }
            eyebrowse = true;

        }
        catch (ClassNotFoundException e) {
            if (!anzu)
                Log.error("Anzu classes do not appear to be in the classpath");
            else
                Log.error("Eyebrowse classes do not appear to be in cp");
        }
        catch (NoSuchMethodException e) {
            if (!anzu)
                Log.error("Anzu classes missing expected method", e);
            else
                Log.error("Eyebrowse classes missing expected method", e);
            throw new RuntimeException("invalid version of Anzu (missing)");
        }
        catch (SecurityException e) {
            if (!anzu)
                Log.error("Anzu req method is not available", e);
            else
                Log.error("Eyebrowse req method is not available", e);
            throw new RuntimeException("Invalid version of Anzu (security)");
        }
    }

d177 2
a178 3
                Object args[] =
                    { p.getDomain().getName(), p.getName(), getListName() };
                mailingListSpec = mailingListSpecConstructor.newInstance(args);
d240 1
a240 7
            MLS_create.invoke(mailingListSpec, null);
            try {
                handleArchiveAddition();
            }
            catch (Exception e) {
                throw new TurbineException("Eyebrowse couldn't create archives", e);
            }
d275 2
a276 3
            Object args[] = { addrs, " "};
            MLS_subscribe.invoke(mailingListSpec, args);
            eyebrowseAddList();
d283 2
a284 1

d305 1
a316 1
            Object args[] = { type };
d318 1
a318 1
                MLS_setListType.invoke(mailingListSpec, args);
d438 1
a438 9
        try {
            String listName = getAddress(null);
            Object args[] = { listName };
            ELM_deleteList.invoke(null, args);
        }
        catch (Exception e) {
            throw new TurbineException("EB deleteList failed: " +
                                       "The database may be in an invalid state", e);
        }
d447 1
a447 1
            MLS_delete.invoke(mailingListSpec, null);
d472 1
a472 5
        if (!anzu) {
            Log.error("Anzu is not installed, so MailingList.* is noop");
            return true;
        }
        else if (!connect()) {
d492 1
a492 1
            return (List)MLS_getListTypes.invoke(mailingListSpec, null);
d509 1
a509 1
            return (List)MLS_getOptionsList.invoke(mailingListSpec, null);
d525 2
a526 6
        try {
            return (List)MLS_getOptionTypes.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
d539 1
a539 1
            return (Map)MLS_getOptionsMap.invoke(mailingListSpec, null);
a556 1
        Object args[] = { option };
d558 1
a558 1
            return (Boolean)MLS_getBooleanOption.invoke(mailingListSpec, args);
d578 1
a578 1
            return (String)MLS_getStringOption.invoke(mailingListSpec, args);
a592 1
        Object args[] = { option, value };
d594 1
a594 1
            MLS_setBooleanOption.invoke(mailingListSpec, args);
d609 3
a611 3
        Object args[] = { option, value };
        try {
            MLS_setStringOption.invoke(mailingListSpec, args);
d613 2
a614 1
        catch (Exception e) {
d628 2
a629 7
        Object args[] = { group };
        try {
            return (ArrayList)MLS_listMembers.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("unable to use Anzu listMembers", e);
        }
a641 1
        Object args[] = { addrs, group };
d643 1
a643 1
            MLS_subscribe.invoke(mailingListSpec, args);
a659 1
        Object args[] = { addrs, group };
d661 1
a661 1
            MLS_unsubscribe.invoke(mailingListSpec, args);
@


1.2
log
@adding files from the branch to the head
@
text
@d6 1
a6 1
import org.apache.turbine.om.BaseObject;
d28 1
a28 1
 * @@version $Id: MailingList.java,v 1.1.1.1 2001/02/21 00:32:56 dlr Exp $
d287 1
a287 1
        ml.setProjectId(project.getProjectId());
d512 1
a512 1
        return String.valueOf(getMailinglistId());
d616 1
a616 2
        acl.assertPermission("Mailing List - " + operation,
                                       getProject());
@


1.1
log
@file MailingList.java was initially added on branch HELM_PEER_PORT_BRANCH.
@
text
@d1 838
@


1.1.1.1
log
@Replacing the HEAD with the HELM_PEER_PORT_BRANCH.
@
text
@a0 838
package org.tigris.helm.om;

import java.util.*;
import java.lang.reflect.*;

import org.apache.turbine.om.BaseObject;
import org.apache.turbine.om.peer.BasePeer;
import org.apache.turbine.util.db.Criteria;
import org.apache.turbine.util.ObjectUtils;
import org.apache.turbine.util.StringUtils;
import org.apache.turbine.util.ParameterParser;
import org.apache.turbine.util.*;
import org.apache.turbine.util.db.pool.DBConnection;

import org.joist.util.JoistProperties;

import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.base.*;
import org.tigris.helm.security.*;
import org.tigris.helm.*;

/**
 * Mailing list business rules.
 *
 * @@author <a href="mailto:elicia@@collab.net">Elicia David</a>
 * @@author <a href="mailto:edk@@collab.net">Ed Korthof</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@version $Id: MailingList.java,v 1.1.2.20 2001/02/20 18:10:23 dlr Exp $
 *
 * MailingList objects correspond to mailing lists, and are used to modify
 * the settings for given mailing lists, manage the subscription list,
 * and so on.
 *
 * The term group is used to describe the different lists of email addresses
 * which may be associated with a given mailing list; some examples include:
 * normal subscribers, moderators, digest subscribers, and (for ezmlm) the
 * allow list.
 */
public class MailingList extends BaseMailingList
{
    /**
     * Where should archive e-mail go
     */
    protected static String mailArchiveHost = null;

    /**
     * The prefix required for lists and addresses.
     */
    protected static String mailPrefix = null;

    static
    {
        try
        {
            org.joist.util.JoistProperties properties
                = org.joist.util.JoistProperties.getInstance( );
            if( properties == null )
            {
                throw new NullPointerException( "JoistProperties is null" );
            }

            // this is silly ... but follows the pattern. 
            final String MAIL_PREFIX_KEY = "mail_prefix";
            final String MAIL_ARCHIVE_HOST_KEY = "mail_archive_host";

            mailArchiveHost = properties.getProperty("mail_archive_host");
            if (mailArchiveHost == null)
            {
                Log.error("mail_archive_host missing; archiver addresses " +
                        "will not be subscribed automatically");
            }

            mailPrefix = properties.getProperty("mail_prefix");
            if (mailPrefix == null)
            {
                mailPrefix = "";
            }
        }
        catch (Exception e)
        {
            Log.error("unable to read stuff from joist properties", e);
        }
    }

    /**
     * Groups correspond to different lists of email addresses associated
     * with a single mailing list.
     */

    /**
     * Normal subscribers
     */
    public static String SUBSCRIBER_GROUP = "";

    /**
     * Moderators
     */
    public static String MODERATOR_GROUP = "mod";

    /**
     * Digest subscribers
     */
    public static String DIGEST_GROUP = "digest";

    /**
     * The allow list
     */
    public static String ALLOW_GROUP = "allow";

    protected static Constructor mailingListSpecConstructor = null;
    protected static Method MLS_create = null; // void
    protected static Method MLS_update = null; // void
    protected static Method MLS_delete = null; // void
    protected static Method MLS_setListType = null; //void
    protected static Method MLS_setBooleanOption = null; //void
    protected static Method MLS_setStringOption = null; //void
    protected static Method MLS_getBooleanOption = null; //void
    protected static Method MLS_getStringOption = null; //void
    protected static Method MLS_getListTypes = null; //List
    protected static Method MLS_getOptionTypes = null; //List
    protected static Method MLS_getOptionsMap = null; //List
    protected static Method MLS_getOptionsList = null; //List
    protected static Method MLS_subscribe = null; //void
    protected static Method MLS_unsubscribe = null; //void
    protected static Method MLS_listMembers = null; //List
    protected static Method ELM_deleteList = null; //void
    protected static Method ELM_addList = null; // void
    protected static Method ELM_addListFile = null; // void

    private static boolean anzu = false;
    private static boolean eyebrowse = false;

    private Object mailingListSpec = null;
    private boolean exists = true;
    private User owner = null;

    static
    {
        try {
            Class MLSClass =
                Class.forName("org.tigris.anzu.client.MailingListSpec");
            {
                Class argTypes[] = {
                        String.class, String.class, String.class
                };
                mailingListSpecConstructor =
                    MLSClass.getConstructor(argTypes);
            }

            {
                Class argTypes[] = {};
                MLS_create = MLSClass.getDeclaredMethod("create", argTypes);
                MLS_update = MLSClass.getDeclaredMethod("update", argTypes);
                MLS_delete = MLSClass.getDeclaredMethod("delete", argTypes);
                MLS_getOptionsList =
                    MLSClass.getDeclaredMethod("getOptionsList", argTypes);
                MLS_getOptionsMap =
                    MLSClass.getDeclaredMethod("getOptionsMap", argTypes);
                MLS_getOptionTypes =
                    MLSClass.getDeclaredMethod("getOptionTypes", argTypes);
                MLS_getListTypes =
                    MLSClass.getDeclaredMethod("getListTypes", argTypes);
            }

            {
                Class argTypes[] = {
                    List.class, String.class
                };
                MLS_subscribe =
                    MLSClass.getDeclaredMethod("subscribe", argTypes);
                MLS_unsubscribe =
                    MLSClass.getDeclaredMethod("unsubscribe", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class
                };
                MLS_setListType =
                    MLSClass.getDeclaredMethod("setListType", argTypes);
                MLS_getBooleanOption =
                    MLSClass.getDeclaredMethod("getBooleanOption", argTypes);
                MLS_getStringOption =
                    MLSClass.getDeclaredMethod("getStringOption", argTypes);
                MLS_listMembers =
                    MLSClass.getDeclaredMethod("listMembers", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, String.class
                };
                MLS_setStringOption =
                    MLSClass.getDeclaredMethod("setStringOption", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, Boolean.class
                };
                MLS_setBooleanOption =
                    MLSClass.getDeclaredMethod("setBooleanOption", argTypes);
            }
            anzu = true;

            Class ELMClass =
                Class.forName("org.tigris.eyebrowse.ListMaint");
            {
                Class argTypes[] = {
                    String.class
                };
                ELM_deleteList =
                    ELMClass.getDeclaredMethod("deleteList", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, String.class
                };
                ELM_addListFile = // String list name, String filename
                    ELMClass.getDeclaredMethod("addListFile", argTypes);
            }
            {
                Class argTypes[] = {
                    String.class, String.class, Integer.class
                };
                ELM_addList = // String listName, String desc, String ID
                    ELMClass.getDeclaredMethod("addList", argTypes);
            }
            eyebrowse = true;

        }
        catch (ClassNotFoundException e) {
            if (!anzu)
                Log.error("Anzu classes do not appear to be in the classpath");
            else
                Log.error("Eyebrowse classes do not appear to be in cp");
        }
        catch (NoSuchMethodException e) {
            if (!anzu)
                Log.error("Anzu classes missing expected method", e);
            else
                Log.error("Eyebrowse classes missing expected method", e);
            throw new RuntimeException("invalid version of Anzu (missing)");
        }
        catch (SecurityException e) {
            if (!anzu)
                Log.error("Anzu req method is not available", e);
            else
                Log.error("Eyebrowse req method is not available", e);
            throw new RuntimeException("Invalid version of Anzu (security)");
        }
    }

    /**
     * Adds a new mailing list to the specified project.
     *
     * @@param acl      The ACL to check for permission.
     * @@param project  The project to add the mailing list to.
     * @@param listName The name of the list to add.
     * @@return         The mailing list just added.
     */
    public static MailingList add(AccessControlList acl, Project project,
                                  String listName)
        throws ACLException, Exception
    {
        return add(acl, project, listName, null, null);
    }

    /**
     * Adds a new mailing list to the specified project.
     *
     * @@param acl      The ACL to check for permission.
     * @@param project  The project to add the mailing list to.
     * @@param listName The name of the list to add.
     * @@param descrip  The list description, or <code>null</code> for none.
     * @@param type     The type of mailing list to add, or
     *                 <code>null</code> for unspecified.
     * @@return         The mailing list just added.
     */
    public static MailingList add(AccessControlList acl, Project project,
                                  String listName, String descrip, String type)
        throws ACLException, Exception
    {
        acl.assertPermission("Mailing List - Add", project);
        MailingList ml = new MailingList();
        ml.setProjectId(project.getProjectId());
        ml.setListName(listName);
        if (descrip == null) {
            descrip = "";
        }
        ml.setDescription(descrip);
        if (type != null) {
            ml.setType(type);
        }
        ml.save();
        ml.mailingListSpec = null;
        ml.exists = true;
        // owner is not used in this context (it's in creating new lists):
        ml.owner = null;
        return ml;
    }

    /**
     * This method is used to connect with the Anzu classes.  It does
     * implicitly connect to the remote anzu server.  It uses reflection
     * to avoid requiring Anzu to compile.
     * 
     * @@return Whether or not the connection attempt was successful.
     */
    public boolean connect()
    {
        if (mailingListSpec == null) {
            try {
                Project p = getProject();
                Object args[] =
                    { p.getDomain().getName(), p.getName(), getListName() };
                mailingListSpec = mailingListSpecConstructor.newInstance(args);
                setStringOption("mail_prefix", mailPrefix);
            }
            catch (Exception e) {
                Log.warn("Error trying to connect to Anzu", e);
                mailingListSpec = null;
                return false;
            }
        }
        return true;
    }

    /**
     * This method will either create or update the existing list.
     */
    public void save(AccessControlList acl)
        throws ACLException, AlreadyExists, TurbineException, Exception
    {
        if (anzuDisabled()) return;
        checkPermission(acl, "Add");

        if (owner != null) {
            setStringOption("owner", owner.getEmail());
        }
        if (exists) {
            update();
        }
        else {
            create();
        }
        if (owner != null) {
            try {
                List autoSubscribe = new ArrayList();
                autoSubscribe.add(owner.getEmail());
                subscribe(autoSubscribe, "mod");
                subscribe(autoSubscribe, "allow");
            }
            catch (Exception e) {
                Log.error("Unable to add owner to mod/allow: " +
                          owner.getEmail());
            }
        }
    }

    /**
     * Updates an existing list
     */
    private void update()
        throws AlreadyExists, TurbineException, Exception
    {
        //TODO : implement this
    }

    /**
     * Creates the the list.
     */
    private void create()
        throws AlreadyExists, TurbineException, Exception
    {
        MailingListPeer.doInsert(this);

        try {
            MLS_create.invoke(mailingListSpec, null);
            try {
                handleArchiveAddition();
            }
            catch (Exception e) {
                throw new TurbineException("Eyebrowse couldn't create archives", e);
            }
        }
        catch (Exception e) {
            try {
                MailingListPeer.doDelete(this);
            }
            catch (Exception rollbackFailed) {
                throw new TurbineException
                    ("Error trying to roll back addition of mailing " +
                     "list to database after Anzu error; the database " +
                     "may not be in a consistent state!", rollbackFailed);
            }
            throw new TurbineException("Anzu failed to create mailing list", e);
        }

        exists = true;
    }

    /**
     * Delets this mailing list.
     */
    public void delete(AccessControlList acl)
        throws ACLException, Exception
    {
        checkPermission(acl, "Delete");
        delete();
    }

    protected void handleArchiveAddition()
        throws Exception
    {
        Log.debug("Trying to add archiver to mailing list");
        if (mailArchiveHost != null) {
            List addrs = new ArrayList();
            addrs.add(getArchiveAddress());
            Object args[] = { addrs, " "};
            MLS_subscribe.invoke(mailingListSpec, args);
            eyebrowseAddList();
        }
        else {
            Log.warn("Not adding archiver to list " + getListName() +
                     " in project " + getProject().getName());
        }
    }

    protected void eyebrowseAddList()
        throws Exception
    {
        Log.debug("Trying to add mailing list file with Eyebrowse");
        String listName = getAddress(null);
        {
            Object args[] = { listName, getDescription(),
                              Integer.valueOf(getID()) };
            ELM_addList.invoke(null, args);
        }
        {
            Project p = getProject();
            Object args[] = { listName,
                              JoistProperties.getProperty("SANDBOX") +
                              "/data/eyebrowse/" + p.getDomain().getName() +
                              '/' + p.getName() + '/' + getListName() +
                              "/0mbox" };
            ELM_addListFile.invoke(null, args);
        }
    }

    /**
     * Extends the functionality of the base class to also invoke the
     * dynamic <code>MLS_setListType</code> method and to set list
     * options.
     */
    public void setType(String type)
    {
        super.setType(type);
        try {
            if (anzuDisabled()) return;
            Object args[] = { type };
            try {
                MLS_setListType.invoke(mailingListSpec, args);
            }
            catch (Exception e) {
                throw new TurbineException("Anzu error", e);
            }
            // This is part of the business logic -- it belongs here.  It
            // needs to be called every time setType is because setType
            // will overwrite all the current options ...
            if (mailPrefix != null) {
                setStringOption("mail_prefix", mailPrefix);
            }
        }
        catch (Exception e) {
            Log.error("Connection to Anzu server failed: " +
                      e.getMessage(), e);
            return;
        }
    }

    /**
     * Sets the owner of this mailing list.  Also sets list options.
     *
     * @@param owner The owner of the list.
     */
    public void setOwner(User owner)
        throws TurbineException, Exception
    {
        this.owner = owner;
        if (exists) {
            setStringOption("owner", owner.getEmail());
        }
    }

    /**
     * Returns whether the list has been created yet (MailingList objects
     * must be explicitly created before they exist in the file system/
     * permanently).
     */
    public boolean exists()
    {
        return exists;
    }

    /**
     * Gets the primary database key of this mailing list.
     */
    public final String getID()
    {
        return String.valueOf(getMailinglistId());
    }

    /**
     * TODO: Document.
     */
    public String getArchiveAddress()
        throws Exception
    {
        String addr = null;
        if (mailArchiveHost != null) {
            Project p = getProject();
            addr = mailPrefix + "archive=mail-" + p.getName() + '=' +
                getListName() + '=' + p.getDomain().getName() + '@@' +
                mailArchiveHost;
        }
        else {
            Log.warn("Unable to determine mail archive address, since " +
                     "mail_archive_host property was not set");
        }
        return addr;
    }

    /**
     * This is used by templates to get the appropriate list prefix.
     * For vhosted lists, that's getName() ; but for non-vhosted list,
     * it'll be project-getName().
     */
    public String getEmailPrefix()
    {
        return mailPrefix + getListName();
    }

    /**
     * If used w/ a null argument or an empty String, it will return
     * the address to post to this list.  Otherwise, it'll return the
     * address for the given command.
     *
     * @@param command The command to run, or <code>null</code> for the posting address.
     * @@return        An e-mail address.
     */
    public String getAddress(String command)
        throws Exception
    {
        StringBuffer addr = new StringBuffer(getEmailPrefix());
        if (command != null && !command.equals("")) {
            addr.append('-').append(command);
        }
        return addr.append('@@').append(getEmailDomain()).toString();
    }

    /**
     * Returns the email domain of the list (i.e. <code>foo.com
     */
    protected final String getEmailDomain()
        throws Exception
    {
        Project project = getProject();
        String projectName = project.getName();
        if (projectName.equals(ProjectPeer.DEFAULT_PROJECT_NAME))
            return project.getDomain().getName();
        else 
            return project.getName() + '.' + project.getDomain().getName();
    }

    /**
     * Internal delete, with no permission checking (NC).
     */
    protected void delete()
        throws Exception
    {
        if (anzuDisabled()) return;
        try {
            String listName = getAddress(null);
            Object args[] = { listName };
            ELM_deleteList.invoke(null, args);
        }
        catch (Exception e) {
            throw new TurbineException("EB deleteList failed: " +
                                       "The database may be in an invalid state", e);
        }
        try {
            MailingListPeer.doDelete(this);
        }
        catch (Exception e) {
            throw new TurbineException("MailingListPeer.doDelete failed: " +
                                       "The database may be in an invalid state", e);
        }
        try {
            MLS_delete.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu delete mailing list failed: " +
                                       "The database may be in an invalid state", e);
        }
    }

    /**
     * Checks the provided ACL for the permission indicated by the mailing
     * list operation.
     */
    private final void checkPermission(AccessControlList acl, String operation)
        throws ACLException, Exception
    {
        acl.assertPermission("Mailing List - " + operation,
                                       getProject());
    }

    /**
     * Checks whether Anzu is disabled, and whether the Anzu server can be
     * connected to.
     */
    private boolean anzuDisabled()
        throws Exception
    {
        if (!anzu) {
            Log.error("Anzu is not installed, so MailingList.* is noop");
            return true;
        }
        else if (!connect()) {
            Log.error("Unable to connect to Anzu server; bailing out");
            throw new Exception("Anzu is installed but the server " +
                                "is not running");
        }
        else {
            return false;
        }
    }

    /**
     * Returns the available mailing list types.
     *
     * @@return Available list types.
     */
    public List getListTypes()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (List)MLS_getListTypes.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public List getOptionsList()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (List)MLS_getOptionsList.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public List getOptionTypes()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (List)MLS_getOptionTypes.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public Map getOptionsMap()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (Map)MLS_getOptionsMap.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * Gets a <code>Boolean</code> parameter for a dynamically invoked
     * method.
     *
     * @@param option Name of the parameter to get the value of.
     * @@return       Parameter value.
     */
    public Boolean getBooleanOption(String option)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        Object args[] = { option };
        try {
            return (Boolean)MLS_getBooleanOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * Gets a <code>String</code> parameter for a dynamically invoked
     * method.
     *
     * @@param option Name of the parameter to get the value of.
     * @@return       Parameter value.
     */
    public String getStringOption(String option)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        Object args[] = { option };
        try {
            return (String)MLS_getStringOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * Sets a <code>Boolean</code> parameter for a dynamically invoked
     * method.
     */
    public void setBooleanOption(String option, Boolean value)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return;
        Object args[] = { option, value };
        try {
            MLS_setBooleanOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * Sets a <code>String</code> parameter for a dynamically invoked
     * method.
     */
    public void setStringOption(String option, String value)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return;
        Object args[] = { option, value };
        try {
            MLS_setStringOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * Lists the subscribers in a group on the mailing list
     *
     * @@param group The group (use the public _GROUP symbols in this class)
     * @@return a List of email addresses constituting the subscriber list
     */
    public List listMembers(String group) throws TurbineException, Exception
    {   
        if (anzuDisabled()) return null;
        Object args[] = { group };
        try {
            return (ArrayList)MLS_listMembers.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("unable to use Anzu listMembers", e);
        }
    }

    /**
     * Subscribes a list of email addresses to a group.
     *
     * @@param addrs The email addresses to subscribe.
     * @@param group The group (use the public _GROUP symbols in this class)
     */
    public void subscribe(List addrs, String group)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return;
        Object args[] = { addrs, group };
        try {
            MLS_subscribe.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Unable to use Anzu subscribe", e);
        }
    }

    /**
     * Unsubscribes a list of email addresses from a group.
     *
     * @@param addrs The email addresses to unsubscribe.
     * @@param group The group (use the public _GROUP symbols in this class)
     */
    public void unsubscribe(List addrs, String group) 
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return;
        Object args[] = { addrs, group };
        try {
            MLS_unsubscribe.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Unable to use Anzu unsubscribe", e);
        }
    }
}
@


1.1.2.1
log
@Classes ported to the Turbine Peer system. -dlr and leonardr
@
text
@a0 20
package org.tigris.helm.om;

import java.util.*;

import org.apache.turbine.om.BaseObject;
import org.apache.turbine.om.peer.BasePeer;
import org.apache.turbine.util.db.Criteria;
import org.apache.turbine.util.ObjectUtils;
import org.apache.turbine.util.StringUtils;
import org.apache.turbine.util.ParameterParser;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.db.pool.DBConnection;

import org.tigris.helm.om.peer.*;

/** 
 */
public class MailingList extends BaseMailingList
{
}
@


1.1.2.2
log
@Port of mailing list basics.
@
text
@a3 1
import java.lang.reflect.*;
a16 1
 * @@version $Id: $
a19 138
    protected static Constructor mailingListSpecConstructor = null;
    protected static Method MLS_create = null; // void
    protected static Method MLS_update = null; // void
    protected static Method MLS_delete = null; // void
    protected static Method MLS_setListType = null; //void
    protected static Method MLS_setBooleanOption = null; //void
    protected static Method MLS_setStringOption = null; //void
    protected static Method MLS_getBooleanOption = null; //void
    protected static Method MLS_getStringOption = null; //void
    protected static Method MLS_getListTypes = null; //List
    protected static Method MLS_getOptionTypes = null; //List
    protected static Method MLS_getOptionsMap = null; //List
    protected static Method MLS_getOptionsList = null; //List
    protected static Method MLS_subscribe = null; //ArrayList
    protected static Method MLS_unsubscribe = null; //void
    protected static Method MLS_listMembers = null; //void
    protected static Method ELM_deleteList = null; //void
    protected static Method ELM_addList = null; // void
    protected static Method ELM_addListFile = null; // void

    private Object mailingListSpec = null;
    private boolean exists = true;
    private static boolean anzu = false;
    private static boolean eyebrowse = false;

    static {
        try {
            Class MLSClass =
                Class.forName("org.tigris.anzu.client.MailingListSpec");
            {
                Class argTypes[] = {
                        String.class, String.class, String.class
                };
                mailingListSpecConstructor =
                    MLSClass.getConstructor(argTypes);
            }

            {
                Class argTypes[] = {};
                MLS_create = MLSClass.getDeclaredMethod("create", argTypes);
                MLS_update = MLSClass.getDeclaredMethod("update", argTypes);
                MLS_delete = MLSClass.getDeclaredMethod("delete", argTypes);
                MLS_getOptionsList =
                    MLSClass.getDeclaredMethod("getOptionsList", argTypes);
                MLS_getOptionsMap =
                    MLSClass.getDeclaredMethod("getOptionsMap", argTypes);
                MLS_getOptionTypes =
                    MLSClass.getDeclaredMethod("getOptionTypes", argTypes);
                MLS_getListTypes =
                    MLSClass.getDeclaredMethod("getListTypes", argTypes);
            }

            {
                Class argTypes[] = {
                    ArrayList.class, String.class
                };
                MLS_subscribe =
                    MLSClass.getDeclaredMethod("subscribe", argTypes);
                MLS_unsubscribe =
                    MLSClass.getDeclaredMethod("unsubscribe", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class
                };
                MLS_setListType =
                    MLSClass.getDeclaredMethod("setListType", argTypes);
                MLS_getBooleanOption =
                    MLSClass.getDeclaredMethod("getBooleanOption", argTypes);
                MLS_getStringOption =
                    MLSClass.getDeclaredMethod("getStringOption", argTypes);
                MLS_listMembers =
                    MLSClass.getDeclaredMethod("listMembers", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, String.class
                };
                MLS_setStringOption =
                    MLSClass.getDeclaredMethod("setStringOption", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, Boolean.class
                };
                MLS_setBooleanOption =
                    MLSClass.getDeclaredMethod("setBooleanOption", argTypes);
            }
            anzu = true;

            Class ELMClass =
                Class.forName("org.tigris.eyebrowse.ListMaint");
            {
                Class argTypes[] = {
                    String.class
                };
                ELM_deleteList =
                    ELMClass.getDeclaredMethod("deleteList", argTypes);
            }

            {
                Class argTypes[] = {
                    String.class, String.class
                };
                ELM_addListFile = // String list name, String filename
                    ELMClass.getDeclaredMethod("addListFile", argTypes);
            }
            {
                Class argTypes[] = {
                    String.class, String.class, Integer.class
                };
                ELM_addList = // String listName, String desc, String ID
                    ELMClass.getDeclaredMethod("addList", argTypes);
            }
            eyebrowse = true;

        } catch (ClassNotFoundException e) {
            if (!anzu)
                Log.error("Anzu classes do not appear to be in the classpath");
            else
                Log.error("Eyebrowse classes do not appear to be in cp");
        } catch (NoSuchMethodException e) {
            if (!anzu)
                Log.error("Anzu classes missing expected method", e);
            else
                Log.error("Eyebrowse classes missing expected method", e);
            throw new RuntimeException("invalid version of Anzu (missing)");
        } catch (SecurityException e) {
            if (!anzu)
                Log.error("Anzu req method is not available", e);
            else
                Log.error("Eyebrowse req method is not available", e);
            throw new RuntimeException("Invalid version of Anzu (security)");
        }
    }
@


1.1.2.3
log
@Ported much more mailing list code.
@
text
@d12 1
a12 1
import org.apache.turbine.util.*;
a15 1
import org.tigris.helm.security.*;
d18 1
a18 1
 * @@version $Id: MailingList.java,v 1.1.2.2 2001/02/10 21:16:21 dlr Exp $
a21 10
    /**
     * Where should archive e-mail go
     */
    protected static String mailArchiveHost = null;

    /**
     * The prefix required for lists and addresses.
     */
    protected static String mailPrefix = null;

a157 170
        }
    }

    /**
     * This method is used to connect with the Anzu classes.  It does
     * implicitly connect to the remote anzu server.  It uses reflection
     * to avoid requiring Anzu to compile.
     * 
     * @@return Whether or not the connection attempt was successful.
     */
    public boolean connect()
    {
        if (mailingListSpec == null) {
            try {
                Project p = getProject();
                Object args[] = { p.getDomain(), p, getListName() };
                mailingListSpec = mailingListSpecConstructor.newInstance(args);
                setStringOption("mail_prefix", mailPrefix);
            }
            catch (Exception e) {
                Log.warn("Error trying to connect to Anzu", e);
                mailingListSpec = null;
                return false;
            }
        }
        return true;
    }

    /**
     * Delets this mailing list.
     */
    public void delete(AccessControlList acl)
        throws ACLException, Exception
    {
        checkPermission(acl, "Delete");
        delete();
    }

    /**
     * This is used by templates to get the appropriate list prefix.
     * For vhosted lists, that's getName() ; but for non-vhosted list,
     * it'll be project-getName().
     */
    public String getEmailPrefix()
    {
        return mailPrefix + getListName();
    }

    /**
     * If used w/ a null argument or an empty String, it will return
     * the address to post to this list.  Otherwise, it'll return the
     * address for the given command.
     *
     * @@param command The command to run, or <code>null</code> for the posting address.
     * @@return        An e-mail address.
     */
    public String getAddress(String command)
        throws Exception
    {
        StringBuffer addr = new StringBuffer(getEmailPrefix());
        if (command != null && !command.equals("")) {
            addr.append('-').append(command);
        }
        return addr.append('@@').append(getEmailDomain()).toString();
    }

    /**
     * Returns the email domain of the list (i.e. <code>foo.com
     */
    protected final String getEmailDomain()
        throws Exception
    {
        Project p = getProject();
        return (p.getName() + '.' + p.getDomain().getName());
    }

    /**
     * Internal delete, with no permission checking (NC).
     */
    protected void delete()
        throws Exception
    {
        if (anzuDisabled()) return;
        try {
            String listName = getAddress(null);
            Object args[] = { listName };
            ELM_deleteList.invoke(null, args);
        }
        catch (Exception e) {
            throw new TurbineException("EB deleteList failed: " +
                                       "The database may be in an invalid state", e);
        }
        try {
            MailingListPeer.doDelete(this);
        }
        catch (Exception e) {
            throw new TurbineException("MailingListPeer.doDelete failed: " +
                                       "The database may be in an invalid state", e);
        }
        try {
            MLS_delete.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu delete mailing list failed: " +
                                       "The database may be in an invalid state", e);
        }
    }

    /**
     * Checks the provided ACL for the permission indicated by the mailing
     * list operation.
     */
    private void checkPermission(AccessControlList acl, String operation)
        throws ACLException, Exception
    {
        acl.assertPermissionForProject("Mailing List - " + operation,
                                       getProject());
    }

    /**
     * Checks whether Anzu is disabled.
     */
    private boolean anzuDisabled()
        throws Exception
    {
        if (!anzu) {
            Log.error("Anzu is not installed, so MailingList.* is noop");
            return true;
        }
        else if (!connect()) {
            Log.error("Unable to connect to anzu server; bailing out");
            throw new Exception("Anzu is installed but the server " +
                                "is not running");
        }
        return false;
    }

    /**
     * Sets a <code>Boolean</code> parameter for a dynamically invoked
     * method.
     */
    public void setBooleanOption(String option, Boolean value)
        throws Exception
    {
        if (anzuDisabled()) return;

        Object args[] = { option, value };
        try {
            MLS_setBooleanOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * Sets a <code>String</code> parameter for a dynamically invoked
     * method.
     */
    public void setStringOption(String option, String value)
        throws Exception
    {
        if (anzuDisabled()) return;

        Object args[] = { option, value };
        try {
            MLS_setStringOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
@


1.1.2.4
log
@Inline checkPermission().
@
text
@d19 1
a19 1
 * @@version $Id: MailingList.java,v 1.1.2.3 2001/02/10 22:07:10 dlr Exp $
d281 1
a281 1
    private final void checkPermission(AccessControlList acl, String operation)
@


1.1.2.5
log
@Changed code to no longer use deprecated methods.
@
text
@d19 1
a19 1
 * @@version $Id: MailingList.java,v 1.1.2.4 2001/02/10 22:32:05 dlr Exp $
d284 1
a284 1
        acl.assertPermission("Mailing List - " + operation,
@


1.1.2.6
log
@Ported subscribe() and unsubscribe() to new API.  Now takes a List of
email addresses instead of an ArrayList like previously.  Ed is making
the appropriate changes to the corresponding branch of Anzu to support
this.
@
text
@d18 2
a19 7
/**
 * Mailing list business rules.
 *
 * @@author <a href="mailto:elicia@@collab.net">Elicia David</a>
 * @@author <a href="mailto:edk@@collab.net">Ed Korthof</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@version $Id: MailingList.java,v 1.1.2.5 2001/02/12 16:24:32 leonardr Exp $
a338 38
        }
    }

    /**
     * Subscribes a list of email addresses to a group.
     *
     * @@param addrs The email addresses to subscribe.
     * @@param group TODO: Define this.
     */
    public void subscribe(List addrs, String group)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return;
        Object args[] = { addrs, group };
        try {
            MLS_subscribe.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Unable to use Anzu subscribe", e);
        }
    }

    /**
     * Unsubscribes a list of email addresses from a group.
     *
     * @@param addrs The email addresses to unsubscribe.
     * @@param group TODO: Define this.
     */
    public void unsubscribe(List addrs, String group) 
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return;
        Object args[] = { addrs, group };
        try {
            MLS_unsubscribe.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Unable to use Anzu unsubscribe", e);
@


1.1.2.7
log
@* Clarified path through anzuDisabled() method.
* Ported get{Boolean,String}Option() methods.
@
text
@d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.6 2001/02/13 00:03:57 dlr Exp $
d294 1
a294 2
     * Checks whether Anzu is disabled, and whether the Anzu server can be
     * connected to.
d304 1
a304 1
            Log.error("Unable to connect to Anzu server; bailing out");
d308 1
a308 29
        else {
            return false;
        }
    }

    public Boolean getBooleanOption(String option)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        Object args[] = { option };
        try {
            return (Boolean)MLS_getBooleanOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    public String getStringOption(String option)
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        Object args[] = { option };
        try {
            return (String)MLS_getStringOption.invoke(mailingListSpec, args);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
d316 1
a316 1
        throws TurbineException, Exception
d319 1
d334 1
a334 1
        throws TurbineException, Exception
d337 1
@


1.1.2.8
log
@Ported a bunch more methods.
@
text
@d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.7 2001/02/13 00:17:33 dlr Exp $
a313 73
    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public List getListTypes()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (List)MLS_getListTypes.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public List getOptionsList()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (List)MLS_getOptionsList.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public List getOptionTypes()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (List)MLS_getOptionTypes.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
    public Map getOptionsMap()
        throws TurbineException, Exception
    {
        if (anzuDisabled()) return null;
        try {
            return (Map)MLS_getOptionsMap.invoke(mailingListSpec, null);
        }
        catch (Exception e) {
            throw new TurbineException("Anzu error", e);
        }
    }

    /**
     * TODO: Document.
     *
     * @@return TODO
     */
a326 5
    /**
     * TODO: Document.
     *
     * @@return TODO
     */
@


1.1.2.9
log
@Added method for Elicia to add a new mailing list.
@
text
@d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.8 2001/02/13 00:37:48 dlr Exp $
a174 15
    }

    /**
     * Adds a new mailing list to the specified project.
     */
    public static MailingList add(AccessControlList acl, Project project,
                                  String listName)
        throws ACLException, Exception
    {
        acl.assertPermission("Mailing List - Add", project);
        MailingList ml = new MailingList();
        ml.setProjectId(project.getProjectId());
        ml.setListName(listName);
        ml.save();
        return ml;
@


1.1.2.10
log
@Added JavaDoc.
@
text
@d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.9 2001/02/13 02:14:16 dlr Exp $
d330 1
a330 1
     * Returns the available mailing list types.
d332 1
a332 1
     * @@return Available list types.
d398 1
a398 2
     * Gets a <code>Boolean</code> parameter for a dynamically invoked
     * method.
d400 1
a400 2
     * @@param option Name of the parameter to get the value of.
     * @@return       Parameter value.
d416 1
a416 2
     * Gets a <code>String</code> parameter for a dynamically invoked
     * method.
d418 1
a418 2
     * @@param option Name of the parameter to get the value of.
     * @@return       Parameter value.
@


1.1.2.11
log
@JavaDoc'd add().
@
text
@d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.10 2001/02/13 03:57:21 dlr Exp $
d63 1
a63 2
    static
    {
a178 4
     *
     * @@param acl      The ACL to check for permission.
     * @@param project  The project to add the mailing list to.
     * @@param listName The name of the list to add.
@


1.1.2.12
log
@Ported most of the rest of the functionality over from the HEAD.
@
text
@d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.11 2001/02/13 18:50:41 dlr Exp $
d58 2
a62 4
    private Object mailingListSpec = null;
    private boolean exists = true;
    private User owner = null;

a183 1
     * @@return         The mailing list just added.
a193 4
        ml.mailingListSpec = null;
        ml.exists = true;
        // HELP: Who do we set the owner to? The user creating the list?
        ml.owner = null;
a229 55
    }

    /**
     * Extends the functionality of the base class to also invoke the
     * dynamic <code>MLS_setListType</code> method and to set list
     * options.
     */
    public void setType(String type)
    {
        super.setType(type);
        try {
            if (anzuDisabled()) return;
            Object args[] = { type };
            try {
                MLS_setListType.invoke(mailingListSpec, args);
            }
            catch (Exception e) {
                throw new TurbineException("Anzu error", e);
            }
            // This is part of the business logic -- it belongs here.  It
            // needs to be called every time setType is because setType
            // will overwrite all the current options ...
            if (mailPrefix != null) {
                setStringOption("mail_prefix", mailPrefix);
            }
        }
        catch (Exception e) {
            Log.error("Connection to Anzu server failed: " +
                      e.getMessage(), e);
            return;
        }
    }

    /**
     * Sets the owner of this mailing list.  Also sets list options.
     *
     * @@param owner The owner of the list.
     */
    public void setOwner(User owner)
        throws TurbineException, Exception
    {
        this.owner = owner;
        if (exists) {
            setStringOption("owner", owner.getEmail());
        }
    }

    /**
     * Returns whether the list exists or not.
     * <p>
     * HELP: Ed K., would you please add a bit of clarity to the description?
     */
    public boolean exists()
    {
        return exists;
@


1.1.2.13
log
@Added new imports necessitated by Torque.
@
text
@a15 1
import org.tigris.helm.om.base.*;
d24 1
a24 1
 * @@version $Id: MailingList.java,v 1.1.2.12 2001/02/13 20:27:39 dlr Exp $
@


1.1.2.14
log
@* put listMemebers back in this class
* some additional documentation
* symbolic constants for the different group types (which need to be used
  in the servlets)
@
text
@d25 1
a25 10
 * @@version $Id: MailingList.java,v 1.1.2.13 2001/02/16 03:01:27 dlr Exp $
 *
 * MailingList objects correspond to mailing lists, and are used to modify
 * the settings for given mailing lists, manage the subscription list,
 * and so on.
 *
 * The term group is used to describe the different lists of email addresses
 * which may be associated with a given mailing list; some examples include:
 * normal subscribers, moderators, digest subscribers, and (for ezmlm) the
 * allow list.
a38 25
    /**
     * Groups correspond to different lists of email addresses associated
     * with a single mailing list.
     */

    /**
     * Normal subscribers
     */
    public static String SUBSCRIBER_GROUP = "";

    /**
     * Moderators
     */
    public static String MODERATOR_GROUP = "mod";

    /**
     * Digest subscribers
     */
    public static String DIGEST_GROUP = "digest";

    /**
     * The allow list
     */
    public static String ALLOW_GROUP = "allow";

d52 1
a52 1
    protected static Method MLS_subscribe = null; //void
d54 1
a54 1
    protected static Method MLS_listMembers = null; //List
d96 1
a96 1
                    List.class, String.class
d200 1
a200 1
        // owner is not used in this context (it's in creating new lists):
d286 3
a288 3
     * Returns whether the list has been created yet (MailingList objects
     * must be explicitly created before they exist in the file system/
     * permanently).
a539 17
     * Lists the subscribers in a group on the mailing list
     *
     * @@param group The group (use the public _GROUP symbols in this class)
     * @@return a List of email addresses constituting the subscriber list
     */
    public List listMembers(String group) throws TurbineException, Exception
    {   
        if (anzuDisabled()) return null;
        Object args[] = { group };
        try {
            return (ArrayList)MLS_listMembers.invoke(mailingListSpec, args);
        } catch (Exception e) {
            throw new TurbineException("unable to use Anzu listMembers", e);
        }
    }

    /**
d543 1
a543 1
     * @@param group The group (use the public _GROUP symbols in this class)
d562 1
a562 1
     * @@param group The group (use the public _GROUP symbols in this class)
@


1.1.2.15
log
@Overloaded add() method.
@
text
@d25 1
a25 1
 * @@version $Id: MailingList.java,v 1.1.2.14 2001/02/17 20:34:50 edk Exp $
a226 18
        return add(acl, project, listName, null, null);
    }

    /**
     * Adds a new mailing list to the specified project.
     *
     * @@param acl      The ACL to check for permission.
     * @@param project  The project to add the mailing list to.
     * @@param listName The name of the list to add.
     * @@param descrip  The list description, or <code>null</code> for none.
     * @@param type     The type of mailing list to add, or
     *                 <code>null</code> for unspecified.
     * @@return         The mailing list just added.
     */
    public static MailingList add(AccessControlList acl, Project project,
                                  String listName, String descrip, String type)
        throws ACLException, Exception
    {
a230 7
        if (descrip == null) {
            descrip = "";
        }
        ml.setDescription(descrip);
        if (type != null) {
            ml.setType(type);
        }
@


1.1.2.16
log
@* Imported JoistProperties.
* Ported create() and supporting handleArchiveAddition(),
  eyebrowseAddList(), getID(), and getArchiveAddress() methods.
@
text
@a14 2
import org.joist.util.JoistProperties;

a17 1
import org.tigris.helm.*;
d25 1
a25 1
 * @@version $Id: MailingList.java,v 1.1.2.15 2001/02/18 08:41:28 dlr Exp $
a289 51
     * Creates the the list.
     */
    public void create(AccessControlList acl)
        throws ACLException, AlreadyExists, TurbineException, Exception
    {
        if (anzuDisabled()) return;
        checkPermission(acl, "Add");

        if (owner != null) {
            setStringOption("owner", owner.getEmail());
        }

        MailingListPeer.doInsert(this);

        try {
            MLS_create.invoke(mailingListSpec, null);
            try {
                handleArchiveAddition();
            }
            catch (Exception e) {
                throw new TurbineException("Eyebrowse couldn't create archives", e);
            }
        }
        catch (Exception e) {
            try {
                MailingListPeer.doDelete(this);
            }
            catch (Exception rollbackFailed) {
                throw new TurbineException
                    ("Error trying to roll back addition of mailing " +
                     "list to database after Anzu error; the database " +
                     "may not be in a consistent state!", rollbackFailed);
            }
            throw new TurbineException("Anzu failed to create mailing list", e);
        }

        if (owner != null) {
            try {
                List autoSubscribe = new ArrayList();
                autoSubscribe.add(owner.getEmail());
                subscribe(autoSubscribe, "mod");
                subscribe(autoSubscribe, "allow");
            }
            catch (Exception e) {
                Log.error("Unable to add owner to mod/allow: " + owner.getEmail());
            }
        }
        exists = true;
    }

    /**
a298 37
    protected void handleArchiveAddition()
        throws Exception
    {
        Log.debug("Trying to add archiver to mailing list");
        if (mailArchiveHost != null) {
            List addrs = new ArrayList();
            addrs.add(getArchiveAddress());
            Object args[] = { addrs, " "};
            MLS_subscribe.invoke(mailingListSpec, args);
            eyebrowseAddList();
        }
        else {
            Log.warn("Not adding archiver to list " + getListName() +
                     " in project " + getProject().getName());
        }
    }

    protected void eyebrowseAddList()
        throws Exception
    {
        Log.debug("Trying to add mailing list file with Eyebrowse");
        String listName = getAddress(null);
        {
            Object args[] = { listName, getDescription(),
                              Integer.valueOf(getID()) };
            ELM_addList.invoke(null, args);
        }
        {
            Project p = getProject();
            Object args[] = { listName,
                              JoistProperties.getProperty("SANDBOX") +
                              "/data/eyebrowse/" + p.getDomain() + '/' + p +
                              '/' + getListName() + "/0mbox" };
            ELM_addListFile.invoke(null, args);
        }
    }

a351 27
    }

    /**
     * Gets the primary database key of this mailing list.
     */
    public final String getID()
    {
        return String.valueOf(getMailinglistId());
    }

    /**
     * TODO: Document.
     */
    public String getArchiveAddress()
        throws Exception
    {
        String addr = null;
        if (mailArchiveHost != null) {
            Project p = getProject();
            addr = mailPrefix + "archive=mail-" + p + '=' + getListName() +
                '=' + p.getDomain() + '@@' + mailArchiveHost;
        }
        else {
            Log.warn("Unable to determine mail archive address, since " +
                     "mail_archive_host property was not set");
        }
        return addr;
@


1.1.2.17
log
@Corrected the opening and closing of two different blocks on the same
line.
@
text
@d28 1
a28 1
 * @@version $Id: MailingList.java,v 1.1.2.16 2001/02/18 09:16:30 dlr Exp $
d198 1
a198 2
        }
        catch (ClassNotFoundException e) {
d203 1
a203 2
        }
        catch (NoSuchMethodException e) {
d209 1
a209 2
        }
        catch (SecurityException e) {
d728 1
a728 2
        }
        catch (Exception e) {
@


1.1.2.18
log
@* port MailingList* to the peer system
* add some necessary methods to MailingList, update AnzuTask to use those
* this compiles, but some methods still need to be implemented, so it
  doesn't all work
@
text
@d28 1
a28 1
 * @@version $Id: MailingList.java,v 1.1.2.17 2001/02/20 04:32:47 dlr Exp $
d296 1
a296 1
     * This method will either create or update the existing list.
d298 1
a298 1
    public void save(AccessControlList acl)
a306 27
        if (exists) {
            update();
        } else {
            create();
        }
        if (owner != null) {
            try {
                List autoSubscribe = new ArrayList();
                autoSubscribe.add(owner.getEmail());
                subscribe(autoSubscribe, "mod");
                subscribe(autoSubscribe, "allow");
            }
            catch (Exception e) {
                Log.error("Unable to add owner to mod/allow: " +
                        owner.getEmail());
            }
        }
    }

    /**
     * Updates an existing list
     */
    private void update()
        throws AlreadyExists, TurbineException, Exception
    {
        //TODO : implement this
    }
a307 6
    /**
     * Creates the the list.
     */
    private void create()
        throws AlreadyExists, TurbineException, Exception
    {
d332 11
@


1.1.2.19
log
@more code required for normal operation of MailingLists:
* get mail_prefix and mail_archive_host
* use project.getName() whenever dealing with anzu classes, since they
  won't be able to deal with Project or Domain
* handle 'www' project specially (ported from head)
@
text
@d28 1
a28 1
 * @@version $Id: MailingList.java,v 1.1.2.18 2001/02/20 09:49:20 edk Exp $
a50 34
    static
    {
        try
        {
            org.joist.util.JoistProperties properties
                = org.joist.util.JoistProperties.getInstance( );
            if( properties == null )
            {
                throw new NullPointerException( "JoistProperties is null" );
            }

            // this is silly ... but follows the pattern. 
            final String MAIL_PREFIX_KEY = "mail_prefix";
            final String MAIL_ARCHIVE_HOST_KEY = "mail_archive_host";

            mailArchiveHost = properties.getProperty("mail_archive_host");
            if (mailArchiveHost == null)
            {
                Log.error("mail_archive_host missing; archiver addresses " +
                        "will not be subscribed automatically");
            }

            mailPrefix = properties.getProperty("mail_prefix");
            if (mailPrefix == null)
            {
                mailPrefix = "";
            }
        }
        catch (Exception e)
        {
            Log.error("unable to read stuff from joist properties", e);
        }
    }

d282 1
a282 2
                Object args[] =
                    { p.getDomain().getName(), p.getName(), getListName() };
d409 2
a410 3
                              "/data/eyebrowse/" + p.getDomain().getName() +
                              '/' + p.getName() + '/' + getListName() +
                              "/0mbox" };
d487 2
a488 3
            addr = mailPrefix + "archive=mail-" + p.getName() + '=' +
                getListName() + '=' + p.getDomain().getName() + '@@' +
                mailArchiveHost;
d531 2
a532 6
        Project project = getProject();
        String projectName = project.getName();
        if (projectName.equals("www"))
            return project.getDomain().getName();
        else 
            return project.getName() + '.' + project.getDomain().getName();
@


1.1.2.20
log
@* Corrected formatting of both start and end of blocks on the same
  line.
* Used constant for the name of the default project instead of a magic
  string.
@
text
@d28 1
a28 1
 * @@version $Id: MailingList.java,v 1.1.2.19 2001/02/20 13:40:14 edk Exp $
d344 1
a344 2
        }
        else {
d356 1
a356 1
                          owner.getEmail());
d570 1
a570 1
        if (projectName.equals(ProjectPeer.DEFAULT_PROJECT_NAME))
@


