/*
 * 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 org.apache.openejb.config.rules;

import org.apache.openejb.config.EjbModule;
import org.apache.openejb.jee.EnterpriseBean;
import org.apache.openejb.jee.EntityBean;
import org.apache.openejb.jee.MessageDrivenBean;
import org.apache.openejb.jee.PersistenceContextRef;
import org.apache.openejb.jee.PersistenceContextType;
import org.apache.openejb.jee.SessionBean;

/**
 * @version $Rev$ $Date$
 */
public class CheckPersistenceRefs extends ValidationBase {
    public void validate(final EjbModule ejbModule) {

        for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
            if (bean instanceof SessionBean) {
                final SessionBean sessionBean = (SessionBean) bean;
                if (sessionBean.getSessionType() == null) {
                    continue; // skipping since we don't know here what is the type
                }
            }

            final String beanType = getType(bean);
            if (beanType.equals("Stateful")) {
                continue; // skip statefuls and Comp ManagedBean
            }

            for (final PersistenceContextRef ref : bean.getPersistenceContextRef()) {
                if (isExtented(ref)) {
                    String refName = ref.getName();
                    final String prefix = bean.getEjbClass() + "/";
                    if (refName.startsWith(prefix)) {
                        refName = refName.substring(prefix.length());
                    }
                    fail(bean, "persistenceContextExtented.nonStateful", refName, beanType);
                }

            }
        }
    }

    private boolean isExtented(final PersistenceContextRef ref) {
        final PersistenceContextType type = ref.getPersistenceContextType();
        return type != null && type.equals(PersistenceContextType.EXTENDED);
    }

    private String getType(final EnterpriseBean bean) {
        if (bean instanceof SessionBean) {
            final SessionBean sessionBean = (SessionBean) bean;
            switch (sessionBean.getSessionType()) {
                case STATEFUL:
                    return "Stateful";
                case STATELESS:
                    return "Stateless";
                case SINGLETON:
                    return "Singleton";
                case MANAGED:
                    return "Managed";
                default:
                    throw new IllegalArgumentException("Uknown SessionBean type " + bean.getClass());
            }
        } else if (bean instanceof MessageDrivenBean) {
            return "MessageDriven";
        } else if (bean instanceof EntityBean) {
            return "EJB 2.1 Entity";
        } else {
            throw new IllegalArgumentException("Uknown bean type " + bean.getClass());
        }
    }
}
