/** * Copyright (c) 2002-2013 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.cypherdsl; import static org.neo4j.cypherdsl.CypherQuery.identifier; import static org.neo4j.cypherdsl.query.Query.checkNull; import java.util.Arrays; import java.util.regex.Pattern; import org.neo4j.cypherdsl.expression.NumericExpression; import org.neo4j.cypherdsl.expression.ReferenceExpression; import org.neo4j.cypherdsl.expression.StringExpression; import org.neo4j.cypherdsl.query.AbstractExpression; import org.neo4j.cypherdsl.query.Value; /** * Represents an identifier. If the identifier is a node or relationship, * then you can use the property() method to get a representation of individual properties. */ public class Identifier extends Value implements ReferenceExpression { private static final Pattern simpleName = Pattern.compile( "\\p{Alpha}\\w*" ); Identifier( String name ) { super( new IdentifierExpression( name ) ); } Identifier ( Iterable<String> names, String prefix ) { super( new IdentifierExpression(names, prefix) ); } /** * If this identifier represents a node or relationship, * then you can use this method to denote a property. * <p/> * Corresponds to: * <pre> * id.name * </pre> * * @param name * @return */ public Property property( String name ) { return property( identifier( name ) ); } /** * If this identifier represents a node or relationship, * then you can use this method to denote a property. * <p/> * Corresponds to: * <pre> * id.name * </pre> * * @param name * @return */ public Property property( Identifier name ) { checkNull( name, "Name" ); return new Property( this, name); } /** * If this identifier represents a node, * then you can use this method to denote a label. * <p/> * Corresponds to: * <pre> * id:label * </pre> * * @param label * @return */ public LabelReference label( String label ) { return label(identifier(label)); } /** * If this identifier represents a node, * then you can use this method to denote labels. * <p/> * Corresponds to: * <pre> * id:label1:label2 * </pre> * * @param labels * @return */ public LabelReference labels( String... labels ) { checkNull( labels, "Labels" ); return label(new Identifier( Arrays.asList(labels), ":")); } /** * If this identifier represents a node, * then you can use this method to denote labels. * <p/> * Corresponds to: * <pre> * id:label1:label2 * </pre> * * @param labels * @return */ public LabelReference labels( Iterable<String> labels ) { checkNull( labels, "Labels" ); return label(new Identifier( labels, ":")); } /** * If this identifier represents a node, * then you can use this method to denote a label. * <p/> * Corresponds to: * <pre> * id:label * </pre> * * @param label * @return */ public LabelReference label( Identifier label ) { checkNull( label, "Label" ); return new LabelReference( this, label ); } /** * If this identifier represents a node or relationship, * then you can use this method to denote a string property. * <p/> * Corresponds to: * <pre> * id.name * </pre> * * @param name * @return */ public StringExpression string( String name ) { return string( identifier( name ) ); } /** * If this identifier represents a node or relationship, * then you can use this method to denote a string property. * <p/> * Corresponds to: * <pre> * id.name * </pre> * * @param name * @return */ public StringExpression string( Identifier name ) { checkNull( name, "Name" ); return new Property( this, name); } /** * If this identifier represents a node or relationship, * then you can use this method to denote a numeric property. * <p/> * Corresponds to: * <pre> * id.name * </pre> * * @param name * @return */ public NumericExpression number( String name ) { return number( identifier( name ) ); } /** * If this identifier represents a node or relationship, * then you can use this method to denote a numeric property. * <p/> * Corresponds to: * <pre> * id.name * </pre> * * @param name * @return */ public NumericExpression number( Identifier name ) { checkNull( name, "Name" ); return new Property( this, name); } private static class IdentifierExpression extends AbstractExpression { private final String name; private String prefix; private IdentifierExpression( String name ) { this.name = name; } private IdentifierExpression( Iterable<String> names, String prefix ) { StringBuilder nameBuilder = new StringBuilder(); boolean first = true; for ( String name : names ) { if( !first ) { nameBuilder.append( prefix ); } if ( simpleName.matcher( name ).matches() ) { nameBuilder.append( name ); } else { nameBuilder.append( '`' ).append( name ).append( '`' ); } first = false; } this.prefix = prefix; this.name = nameBuilder.toString(); } public void asString( StringBuilder builder ) { if ( prefix != null || simpleName.matcher( name ).matches() ) { builder.append( name ); } else { builder.append( '`' ).append( name ).append( '`' ); } } } }