All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.enonic.xp.site.mapping.ContentMappingConstraint Maven / Gradle / Ivy
package com.enonic.xp.site.mapping;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import com.enonic.xp.annotation.PublicApi;
import com.enonic.xp.app.ApplicationKey;
import com.enonic.xp.content.Content;
import com.enonic.xp.content.ExtraData;
import com.enonic.xp.content.ExtraDatas;
import com.enonic.xp.data.Property;
import com.enonic.xp.data.PropertyTree;
import com.enonic.xp.data.Value;
import com.enonic.xp.data.ValueFactory;
import com.enonic.xp.data.ValueType;
import com.enonic.xp.data.ValueTypes;
import com.enonic.xp.schema.xdata.XDataName;
@PublicApi
public final class ContentMappingConstraint
{
private static final String SEPARATOR = ":";
private static final String ID_PROPERTY = "_id";
private static final String NAME_PROPERTY = "_name";
private static final String PATH_PROPERTY = "_path";
private static final String TYPE_PROPERTY = "type";
private static final String DISPLAY_NAME_PROPERTY = "displayName";
private static final String HAS_CHILDREN_PROPERTY = "hasChildren";
private static final String LANGUAGE_PROPERTY = "language";
private static final String VALID_PROPERTY = "valid";
private static final String DATA_PROPERTY_PREFIX = "data.";
private static final String XDATA_PROPERTY_PREFIX = "x.";
private final String id;
private final String value;
private ContentMappingConstraint( final String id, final String value )
{
this.id = id;
this.value = value;
}
public boolean matches( final Content content )
{
final String val = trimQuotes( this.value );
if ( ID_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.getId().toString() );
}
else if ( NAME_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.getName().toString() );
}
else if ( PATH_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.getPath().toString() );
}
else if ( TYPE_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.getType().toString() );
}
else if ( DISPLAY_NAME_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.getDisplayName() );
}
else if ( HAS_CHILDREN_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.hasChildren() );
}
else if ( LANGUAGE_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.getLanguage() == null ? "" : content.getLanguage().toLanguageTag() );
}
else if ( VALID_PROPERTY.equals( this.id ) )
{
return valueMatches( val, content.isValid() );
}
else if ( this.id.startsWith( DATA_PROPERTY_PREFIX ) )
{
final String dataPath = id.substring( DATA_PROPERTY_PREFIX.length() );
final Property prop = content.getData().getProperty( dataPath );
if ( prop == null || prop.getValue() == null )
{
return false;
}
final Value propertyValue = convert( val, prop.getValue().getType() );
return propertyValue != null && valueMatches( propertyValue.asString(), prop.getValue().asString() );
}
else if ( this.id.startsWith( XDATA_PROPERTY_PREFIX ) )
{
final String dataPath = id.substring( XDATA_PROPERTY_PREFIX.length() );
final String appPrefix;
final String mixinName;
final String propertyName;
final int firstIndex = dataPath.indexOf( "." );
if ( firstIndex == -1 )
{
appPrefix = dataPath;
mixinName = "";
propertyName = "";
}
else
{
appPrefix = dataPath.substring( 0, firstIndex );
final int secondIndex = dataPath.indexOf( ".", firstIndex + 1 );
mixinName = secondIndex == -1 ? dataPath.substring( firstIndex + 1 ) : dataPath.substring( firstIndex + 1, secondIndex );
propertyName = secondIndex == -1 ? "" : dataPath.substring( secondIndex + 1 );
}
final PropertyTree xData = getXData( content.getAllExtraData(), appPrefix, mixinName );
if ( xData == null )
{
return false;
}
final Property prop = xData.getProperty( propertyName );
if ( prop == null || prop.getValue() == null )
{
return false;
}
final Value propertyValue = convert( val, prop.getValue().getType() );
return propertyValue != null && valueMatches( propertyValue.asString(), prop.getValue().asString() );
}
return false;
}
private PropertyTree getXData( final ExtraDatas xDatas, final String appPrefix, final String name )
{
if ( xDatas == null )
{
return null;
}
try
{
final ApplicationKey app = ExtraData.fromApplicationPrefix( appPrefix );
final XDataName xDataName = XDataName.from( app, name );
final ExtraData extraData = xDatas.getMetadata( xDataName );
if ( extraData == null )
{
return null;
}
return extraData.getData();
}
catch ( Exception e )
{
return null;
}
}
private boolean valueMatches( final String pattern, final boolean value )
{
return valueMatches( pattern, Boolean.toString( value ) );
}
private boolean valueMatches( final String pattern, final String value )
{
try
{
return Pattern.compile( pattern ).matcher( value ).matches();
}
catch ( PatternSyntaxException e )
{
return false;
}
}
private Value convert( final String value, final ValueType type )
{
if ( type.equals( ValueTypes.XML ) )
{
return ValueFactory.newXml( ValueTypes.XML.convert( value ) );
}
if ( type.equals( ValueTypes.LOCAL_DATE ) )
{
return ValueFactory.newLocalDate( ValueTypes.LOCAL_DATE.convert( value ) );
}
if ( type.equals( ValueTypes.LOCAL_TIME ) )
{
return ValueFactory.newLocalTime( ValueTypes.LOCAL_TIME.convert( value ) );
}
if ( type.equals( ValueTypes.LOCAL_DATE_TIME ) )
{
return ValueFactory.newLocalDateTime( ValueTypes.LOCAL_DATE_TIME.convert( value ) );
}
if ( type.equals( ValueTypes.DATE_TIME ) )
{
return ValueFactory.newDateTime( ValueTypes.DATE_TIME.convert( value ) );
}
if ( type.equals( ValueTypes.LONG ) )
{
return ValueFactory.newLong( ValueTypes.LONG.convert( value ) );
}
if ( type.equals( ValueTypes.DOUBLE ) )
{
return ValueFactory.newDouble( ValueTypes.DOUBLE.convert( value ) );
}
if ( type.equals( ValueTypes.GEO_POINT ) )
{
return ValueFactory.newGeoPoint( ValueTypes.GEO_POINT.convert( value ) );
}
if ( type.equals( ValueTypes.BOOLEAN ) )
{
return ValueFactory.newBoolean( ValueTypes.BOOLEAN.convert( value ) );
}
if ( type.equals( ValueTypes.REFERENCE ) )
{
return ValueFactory.newReference( ValueTypes.REFERENCE.convert( value ) );
}
if ( type.equals( ValueTypes.LINK ) )
{
return ValueFactory.newLink( ValueTypes.LINK.convert( value ) );
}
if ( type.equals( ValueTypes.BINARY_REFERENCE ) )
{
return ValueFactory.newBinaryReference( ValueTypes.BINARY_REFERENCE.convert( value ) );
}
return ValueFactory.newString( value );
}
private String trimQuotes( final String value )
{
final int length = value.length();
if ( ( length > 1 ) && ( value.charAt( 0 ) == '\'' ) && ( value.charAt( length - 1 ) == '\'' ) )
{
return value.substring( 1, length - 1 );
}
else
{
return value;
}
}
public static ContentMappingConstraint parse( final String expression )
{
int index = expression.indexOf( SEPARATOR );
if ( index == -1 )
{
throw new IllegalArgumentException( "Invalid match expression: " + expression );
}
final String id = expression.substring( 0, index ).trim();
final String value = expression.substring( index + 1 ).trim();
if ( id.isBlank() )
{
throw new IllegalArgumentException( "Invalid match expression: " + expression );
}
return new ContentMappingConstraint( id, value );
}
@Override
public boolean equals( final Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
final ContentMappingConstraint that = (ContentMappingConstraint) o;
return Objects.equals( id, that.id ) && Objects.equals( value, that.value );
}
@Override
public int hashCode()
{
return Objects.hash( id, value );
}
@Override
public String toString()
{
return id + SEPARATOR + value;
}
}