/*
 *  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.jk.core;

import java.util.Hashtable;
import javax.management.ObjectName;

/**
 * The controller object. It manages all other jk objects, acting as the root of
 * the jk object model.
 *
 * @author Gal Shachor
 * @author Henri Gomez [hgomez@apache.org]
 * @author Dan Milstein [danmil@shore.net]
 * @author Keith Wannamaker [Keith@Wannamaker.org]
 * @author Kevin Seguin
 * @author Costin Manolache
 */
public class WorkerEnv {

    Hashtable properties;

    public static final int ENDPOINT_NOTE=0;
    public static final int REQUEST_NOTE=1;
    public static final int SSL_CERT_NOTE=16;
    int noteId[]=new int[4];
    String noteName[][]=new String[4][];
    private Object notes[]=new Object[32];

    Hashtable handlersMap=new Hashtable();
    JkHandler handlersTable[]=new JkHandler[20];
    int handlerCount=0;
    
    // base dir for the jk webapp
    String home;
    int localId=0;
    
    public WorkerEnv() {
        for( int i=0; i<noteId.length; i++ ) {
            noteId[i]=7;
            noteName[i]=new String[20];
        }
    }

    public void setLocalId(int id) {
        localId=id;
    }
    
    public int getLocalId() {
        return localId;
    }
    
    public void setJkHome( String s ) {
        home=s;
    }

    public String getJkHome() {
        return home;
    }
    
    public final Object getNote(int i ) {
        return notes[i];
    }

    public final void setNote(int i, Object o ) {
        notes[i]=o;
    }

    public int getNoteId( int type, String name ) {
        for( int i=0; i<noteId[type]; i++ ) {
            if( name.equals( noteName[type][i] ))
                return i;
        }
        int id=noteId[type]++;
        noteName[type][id]=name;
        return id;
    }

    public void addHandler( String name, JkHandler w ) {
        JkHandler oldH = getHandler(name);
        if(oldH == w) {
            // Already added
            return;
        }
        w.setWorkerEnv( this );
        w.setName( name );
        handlersMap.put( name, w );
        if( handlerCount > handlersTable.length ) {
            JkHandler newT[]=new JkHandler[ 2 * handlersTable.length ];
            System.arraycopy( handlersTable, 0, newT, 0, handlersTable.length );
            handlersTable=newT;
        }
        if(oldH == null) {
            handlersTable[handlerCount]=w;
            w.setId( handlerCount );
            handlerCount++;
        } else {
            handlersTable[oldH.getId()]=w;
            w.setId(oldH.getId());
        }

        // Notify all other handlers of the new one
        // XXX Could be a Coyote action ?
        for( int i=0; i< handlerCount ; i++ ) {
            handlersTable[i].addHandlerCallback( w );
        }
    }

    public final JkHandler getHandler( String name ) {
        return (JkHandler)handlersMap.get(name);
    }

    public final JkHandler getHandler( int id ) {
        return handlersTable[id];
    }

    public final int getHandlerCount() {
        return handlerCount;
    }
    
    public ObjectName[] getHandlersObjectName() {
        
        ObjectName onames[]=new ObjectName[ handlerCount ];
        for( int i=0; i<handlerCount; i++ ) {
            onames[i]=handlersTable[i].getObjectName();
        }
        return onames;
    }

}
