/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed 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.config;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;


/* Naming conventions:

JK_CONF_DIR == serverRoot/work  ( XXX /jkConfig ? )

- Each vhost has a sub-dir named after the canonycal name

- For each webapp in a vhost, there is a separate WEBAPP_NAME.jkmap

- In httpd.conf ( or equivalent servers ), in each virtual host you
should "Include JK_CONF_DIR/VHOST/jk_apache.conf". The config
file will contain the Alias declarations and other rules required
for apache operation. Same for other servers. 

- WebXml2Jk will be invoked by a config tool or automatically for each
webapp - it'll generate the WEBAPP.jkmap files and config fragments.

WebXml2Jk will _not_ generate anything else but mappings.
It should _not_ try to guess locations or anything else - that's
another components' job.

*/

/**
 *
 * @author Costin Manolache
 */
public class GeneratorJk2 implements WebXml2Jk.MappingGenerator {
    WebXml2Jk wxml;
    String vhost;
    String cpath;
    String worker;
    PrintWriter out;
    
    public void setWebXmlReader(WebXml2Jk wxml ) {
        this.wxml=wxml;
        vhost=wxml.vhost;
        cpath=wxml.cpath;
        worker=wxml.worker;
    }

    public void generateStart( ) throws IOException {
        File base=wxml.getJkDir();
        File outF=new File(base, "jk2map.properties");
        out=new PrintWriter( new FileWriter( outF ));

        out.println("# Autogenerated from web.xml" );
    }

    public void generateEnd() {
        out.close();
    }
    
    public void generateServletMapping( String servlet, String url ) {
        out.println( "[uri:" + vhost + cpath + url + "]");
        out.println( "group=" + worker );
        out.println( "servlet=" +  servlet);
        out.println( "host=" +  vhost); 
        out.println( "context=" +  cpath);
        out.println();
    }

    public void generateFilterMapping( String servlet, String url ) {
        out.println( "[url:" + vhost + cpath + url + "]");
        out.println( "group=" + worker );
        out.println( "filter=" +  servlet);
        out.println( "host=" +  vhost); 
        out.println( "context=" +  cpath);
        out.println();
    }

    public void generateLoginConfig( String loginPage,
                                        String errPage, String authM ) {
        out.println("[url:" + vhost + cpath + loginPage  + "]" );
        out.println( "group=" + worker );
        out.println( "host=" +  vhost); 
        out.println( "context=" +  cpath);
        out.println();
        out.println("[url:" + vhost + cpath + errPage  + "]" );
        out.println( "group=" + worker );
        out.println( "host=" +  vhost); 
        out.println( "context=" +  cpath);
        out.println();
    }

    public void generateErrorPage( int err, String location ) {

    }

    public void generateMimeMapping( String ext, String type ) {

    }
    
    public void generateWelcomeFiles( Vector wf ) {

    }
                                            
    
    public void generateConstraints( Vector urls, Vector methods, Vector roles, boolean isSSL ) {
        for( int i=0; i<urls.size(); i++ ) {
            String url=(String)urls.elementAt(i);

            out.println("[url:" + vhost + cpath + url + "]");
            out.println( "group=" + worker );
            out.println( "host=" +  vhost); 
            out.println( "context=" +  cpath);
            for( int j=0; j<roles.size(); j++ ) {
                String role=(String)roles.elementAt(j);
                out.println( "role=" +  role);
            }
            for( int j=0; j<methods.size(); j++ ) {
                String m=(String)methods.elementAt(j);
                out.println( "method=" +  m);
            }
            if( isSSL )
                out.println("ssl=true");
        }
    }
}
