/*******************************************************************************
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
*******************************************************************************/
package com.liferay.ide.core.properties;
import com.liferay.ide.core.util.CoreUtil;
import com.liferay.ide.core.util.StringPool;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.PropertiesConfiguration.PropertiesWriter;
import org.apache.commons.configuration.PropertiesConfigurationLayout;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
/**
* @author Greg Amerson
*/
@SuppressWarnings( "rawtypes" )
public class PortalPropertiesConfigurationLayout extends PropertiesConfigurationLayout
{
public static class PluginPropertiesWriter extends PropertiesWriter
{
/** Constant for the escaping character. */
private static final String ESCAPE = "\\"; //$NON-NLS-1$
/** The list of possible key/value separators */
private static final char[] SEPARATORS = new char[] { '=', ':' };
/** The white space characters used as key/value separators. */
private static final char[] WHITE_SPACE = new char[] { ' ', '\t', '\f' };
private char delimiter;
public PluginPropertiesWriter( Writer writer, char delimiter )
{
super( writer, delimiter );
this.delimiter = delimiter;
}
public void writeProperty( String key, Object value, boolean forceSingleLine, boolean wrappedProperty )
throws IOException
{
String v;
if( value instanceof List )
{
List values = (List) value;
if( forceSingleLine )
{
v = makeSingleLineValue( values );
}
else
{
writeProperty( key, values );
return;
}
}
else if( wrappedProperty )
{
String[] values = value.toString().split( StringPool.COMMA );
if( values.length == 1 )
{
v = escapeValue( values[0] );
}
else
{
StringBuffer buf = new StringBuffer();
for( String val : values )
{
if( CoreUtil.isNullOrEmpty( buf.toString() ) )
{
buf.append( "\\\n" ); //$NON-NLS-1$
buf.append( " " + escapeValue( val ) ); //$NON-NLS-1$
}
else
{
buf.append( ",\\\n " + escapeValue( val ) ); //$NON-NLS-1$
}
}
v = buf.toString();
}
}
else
{
v = escapeValue( value );
}
write( escapeKey( key ) );
write( StringPool.EQUALS );
write( v );
writeln( null );
}
private String escapeKey( String key )
{
StringBuffer newkey = new StringBuffer();
for( int i = 0; i < key.length(); i++ )
{
char c = key.charAt( i );
if( ArrayUtils.contains( SEPARATORS, c ) || ArrayUtils.contains( WHITE_SPACE, c ) )
{
// escape the separator
newkey.append( '\\' );
newkey.append( c );
}
else
{
newkey.append( c );
}
}
return newkey.toString();
}
private String escapeValue( Object value )
{
String escapedValue = StringEscapeUtils.escapeJava( String.valueOf( value ) );
if( delimiter != 0 )
{
escapedValue = StringUtils.replace( escapedValue, String.valueOf( delimiter ), ESCAPE + delimiter );
}
return escapedValue;
}
private String makeSingleLineValue( List values )
{
if( !values.isEmpty() )
{
Iterator it = values.iterator();
String lastValue = escapeValue( it.next() );
StringBuffer buf = new StringBuffer( lastValue );
while( it.hasNext() )
{
// if the last value ended with an escape character, it has
// to be escaped itself; otherwise the list delimiter will
// be escaped
if( lastValue.endsWith( ESCAPE ) )
{
buf.append( ESCAPE ).append( ESCAPE );
}
buf.append( delimiter );
lastValue = escapeValue( it.next() );
buf.append( lastValue );
}
return buf.toString();
}
else
{
return null;
}
}
}
public static final String[] sortedKeys = new String[]
{
"name", //$NON-NLS-1$
"module-group-id", //$NON-NLS-1$
"module-incremental-version", //$NON-NLS-1$
"tags", //$NON-NLS-1$
"short-description", //$NON-NLS-1$
"change-log", //$NON-NLS-1$
"page-url", //$NON-NLS-1$
"author", //$NON-NLS-1$
"licenses", //$NON-NLS-1$
"portal-dependency-jars", //$NON-NLS-1$
"portal-dependency-tlds" //$NON-NLS-1$
};
public PortalPropertiesConfigurationLayout( PropertiesConfiguration config )
{
super( config );
this.setForceSingleLine( true );
}
public boolean isWrappedProperty( String key )
{
return false;
}
public void save( Writer out ) throws ConfigurationException
{
try
{
char delimiter =
getConfiguration().isDelimiterParsingDisabled() ? 0 : getConfiguration().getListDelimiter();
PluginPropertiesWriter writer = new PluginPropertiesWriter( out, delimiter );
if( getHeaderComment() != null )
{
writer.writeln( getCanonicalHeaderComment( true ) );
writer.writeln( null );
}
List<Object> keyList = Arrays.asList( getKeys().toArray() );
Collections.sort( keyList, new Comparator<Object>()
{
public int compare( Object o1, Object o2 )
{
int index1 = Integer.MAX_VALUE;
int index2 = Integer.MAX_VALUE;
for( int i = 0; i < sortedKeys.length; i++ )
{
if( sortedKeys[i].equals( o1 ) )
{
index1 = i;
}
if( sortedKeys[i].equals( o2 ) )
{
index2 = i;
}
}
if( index1 < index2 )
{
return -1;
}
else if( index1 > index2 )
{
return 1;
}
return 0;
}
} );
for( Iterator it = keyList.iterator(); it.hasNext(); )
{
String key = (String) it.next();
if( getConfiguration().containsKey( key ) )
{
// Output blank lines before property
for( int i = 0; i < getBlancLinesBefore( key ); i++ )
{
writer.writeln( null );
}
// Output the comment
if( getComment( key ) != null )
{
writer.writeln( getCanonicalComment( key, true ) );
}
// Output the property and its value
boolean singleLine =
( isForceSingleLine() || isSingleLine( key ) ) &&
!getConfiguration().isDelimiterParsingDisabled();
boolean wrappedProperty = isWrappedProperty( key );
writer.writeProperty( key, getConfiguration().getProperty( key ), singleLine, wrappedProperty );
}
}
writer.flush();
writer.close();
}
catch( IOException ioex )
{
throw new ConfigurationException( ioex );
}
}
}