/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.portal.instruction;
import java.io.IOException;
import java.util.regex.Matcher;
import com.enonic.cms.framework.util.UrlPathDecoder;
/**
* Created by rmy - Date: Nov 18, 2009
*/
public class PostProcessInstructionParser
{
final Matcher matcher;
String currentFunction;
public PostProcessInstructionParser( final String inputString )
{
matcher = PostProcessInstructionPatterns.POST_PROCESS_INSTRUCTION_PATTERN.matcher( inputString );
}
public PostProcessInstruction next()
{
if ( !matcher.find() )
{
return null;
}
currentFunction = matcher.group( 0 );
String prefix = matcher.group( 1 );
String instructionTypeString = matcher.group( 2 );
String separator = matcher.group( 3 );
String serializedInstruction = matcher.group( 4 );
final boolean instructionHasBeenUrlEncoded = PostProcessInstructionPatterns.instructionHasBeenUrlEncoded( prefix );
if ( instructionHasBeenUrlEncoded )
{
instructionTypeString = UrlPathDecoder.decode( instructionTypeString );
separator = UrlPathDecoder.decode( separator );
serializedInstruction = UrlPathDecoder.decode( serializedInstruction );
}
PostProcessInstruction instruction = parsePostProcessInstruction( instructionTypeString, serializedInstruction, separator );
instruction.setDoUrlEncodeResult( instructionHasBeenUrlEncoded );
return instruction;
}
public void appendTail( StringBuffer buffer )
{
matcher.appendTail( buffer );
}
public void replaceInInput( StringBuffer resultBuffer, String replaceString )
{
// Trick to prevent issues with replacement of results containing regexp placeholder symbols:
// replace with empty string, then append the real replacement to stringbuffer directly
matcher.appendReplacement( resultBuffer, "" );
resultBuffer.append( replaceString );
}
public String getCurrentParsedInstuctionString()
{
return currentFunction;
}
private PostProcessInstruction parsePostProcessInstruction( String instructionTypeString, String serializedInstruction,
String separator )
{
PostProcessInstructionType instructionType = parseInstructionType( instructionTypeString );
PostProcessInstruction instruction = createNewInstructionOfType( instructionType );
instruction.setDisableOutputEscaping( !PostProcessInstructionPatterns.instructionHtmlEscaped( separator ) );
instruction.setDoUrlEncodeResult( false );
try
{
instruction.deserialize( serializedInstruction );
return instruction;
}
catch ( IOException e )
{
throw new PostProcessInstructionSerializingException( "Deserialization of PostProcessInstruction failed", e );
}
catch ( ClassNotFoundException e )
{
throw new PostProcessInstructionSerializingException( "Deserialization of PostProcessInstruction failed", e );
}
}
private PostProcessInstructionType parseInstructionType( String typeString )
{
try
{
return PostProcessInstructionType.valueOf( typeString );
}
catch ( IllegalArgumentException e )
{
throw new PostProcessInstructionUnknownTypeException( "Unknown PostProcessInstructionType: " + typeString );
}
}
private PostProcessInstruction createNewInstructionOfType( PostProcessInstructionType type )
{
switch ( type )
{
case CREATE_WINDOWPLACEHOLDER:
return new RenderWindowInstruction();
case CREATE_RESOURCEURL:
return new CreateResourceUrlInstruction();
case CREATE_ATTACHMENTURL:
return new CreateAttachmentUrlInstruction();
case CREATE_IMAGEURL:
return new CreateImageUrlInstruction();
case CREATE_CONTENTURL:
return new CreateContentUrlInstruction();
}
throw new IllegalArgumentException( "PostProcessInstructionType not handled: " + type.name() );
}
}