/****************************************************************
 * 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.                                           *
 ****************************************************************/


/**
 * RFC2183 Content-Disposition parser.
 */

options {
	STATIC=false;
	LOOKAHEAD=1;
	JDK_VERSION = "1.5";
	OUTPUT_DIRECTORY = "../../../../../../../../../target/generated-sources/javacc";
	//DEBUG_PARSER=true;
	//DEBUG_TOKEN_MANAGER=true;
}

PARSER_BEGIN(ContentDispositionParser)
/****************************************************************
 * 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.james.mime4j.field.contentdisposition.parser;

import java.util.List;
import java.util.ArrayList;

public class ContentDispositionParser {

    private String dispositionType;
    private List<String> paramNames = new ArrayList<String>();
    private List<String> paramValues = new ArrayList<String>();

    public String getDispositionType() {
        return dispositionType;
    }

    public List<String> getParamNames() {
        return paramNames;
    }

    public List<String> getParamValues() {
        return paramValues;
    }

    public static void main(String args[]) throws ParseException {
        while (true) {
            try {
                ContentDispositionParser parser = new ContentDispositionParser(
                        System.in);
                parser.parseLine();
            } catch (Exception x) {
                x.printStackTrace();
                return;
            }
        }
    }
}

PARSER_END(ContentDispositionParser)

void parseLine() :
{}
{
	parse() ["\r"] "\n"
}

void parseAll() :
{}
{
	parse() <EOF>
}

void parse() :
{
	Token dispositionType;
}
{
	dispositionType=<ATOKEN>
	{
		this.dispositionType = dispositionType.image;
	}
	( ";" parameter() )*
}

void parameter() :
{
	Token attrib;
	String val;
}
{
	attrib=<ATOKEN> "=" val=value()
	{
		paramNames.add(attrib.image);
		paramValues.add(val);
	}
}

String value() :
{Token t;}
{
(	t=<ATOKEN>
|   t=<DIGITS>
|	t=<QUOTEDSTRING>
)
	{ return t.image; }
}



SPECIAL_TOKEN :
{
 	< WS: ( [" ", "\t"] )+ >
}

TOKEN_MGR_DECLS :
{
	// Keeps track of how many levels of comment nesting
	// we've encountered.  This is only used when the 2nd
	// level is reached, for example ((this)), not (this).
	// This is because the outermost level must be treated
	// specially anyway, because the outermost ")" has a
	// different token type than inner ")" instances.
	static int commentNest;
}

MORE :
{
	// starts a comment
	"(" : INCOMMENT
}

<INCOMMENT>
SKIP :
{
	// ends a comment
	< COMMENT: ")" > : DEFAULT
	// if this is ever changed to not be a SKIP, need
	// to make sure matchedToken.token = token.toString()
	// is called.
}

<INCOMMENT>
MORE :
{
	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
|	"(" { commentNest = 1; } : NESTED_COMMENT
|	< <ANY>>
}

<NESTED_COMMENT>
MORE :
{
	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
|	"(" { ++commentNest; }
|	")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
|	< <ANY>>
}



// QUOTED STRINGS

MORE :
{
	"\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
}

<INQUOTEDSTRING>
MORE :
{
	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
|	< (~["\"", "\\"])+ >
}

<INQUOTEDSTRING>
TOKEN :
{
	< QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() - 1); } : DEFAULT
}


TOKEN :
{
	< DIGITS: ( ["0"-"9"] )+ >
}

TOKEN :
{
	< ATOKEN: ( ~[" ", "\t", "(", ")", "<", ">", "@", ",", ";", ":", "\\", "\"", "/", "[", "]", "?", "="] )+ >
}


// GLOBALS

<*>
TOKEN :
{
	< #QUOTEDPAIR: "\\" <ANY> >
|	< #ANY: ~[] >
}
