/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package flex.messaging.config;

import flex.messaging.security.SecurityException;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
public class SecuritySettings
{
    // Exception/error message numbers.
    private static final int NO_SEC_CONSTRAINT = 10062;

    private String serverInfo;
    private Map loginCommandSettings;
    private Map constraints;
    private boolean recreateHttpSessionAfterLogin;

    public SecuritySettings()
    {
        constraints = new HashMap();
        loginCommandSettings = new HashMap();
    }

    public void addConstraint(SecurityConstraint sc)
    {
        constraints.put(sc.getId(), sc);
    }

    public SecurityConstraint getConstraint(String ref)
    {
        // If an attempt is made to use a constraint that we do not know about,
        // do not let the authorization succeed
        if (constraints.get(ref) == null)
        {
            // Security constraint {0} is not defined.
            SecurityException se = new SecurityException();
            se.setMessage(NO_SEC_CONSTRAINT, new Object[] {ref});
            throw se;
        }
        return (SecurityConstraint)constraints.get(ref);
    }

    public void addLoginCommandSettings(LoginCommandSettings lcs)
    {
        loginCommandSettings.put(lcs.getServer(), lcs);
    }

    public Map getLoginCommands()
    {
        return loginCommandSettings;
    }

    /**
     * Returns a read-only set of constraints.
     *
     * @return the set of security constraints
     */
    public Collection<SecurityConstraint> getConstraints()
    {
        return Collections.unmodifiableCollection(constraints.values());
    }

    public void setServerInfo(String s)
    {
        serverInfo = s;
    }

    public String getServerInfo()
    {
        return serverInfo;
    }

    public boolean isRecreateHttpSessionAfterLogin()
    {
        return recreateHttpSessionAfterLogin;
    }

    public void setRecreateHttpSessionAfterLogin(boolean value)
    {
        recreateHttpSessionAfterLogin = value;
    }
}
