/*
 *  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.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");
        }
    }
}
