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

[[howto-create-constraint,Create a Constraint]]
= Create a Constraint =

Constraints are defined in <<def-constraint>>.

If you want to reproduce what's explained in this tutorial, remember to depend on the Core Bootstrap artifact:

include::../../../../core/bootstrap/build/docs/buildinfo/artifact.txt[]

At runtime you will need the Core Runtime artifact too. See the <<howto-depend-on-polygene>> tutorial for details.

== Method Constraint ==

Method Constraints are declared with annotations on the method argument. The annotation itself is custom, and it is possible to make your own.

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/Dialer.java
tag=dialer
-----------

In the code above we say that we want the argument to the callPhoneNumber() method to be a valid phone number. This annotation is not built-in, so we need to declare it.

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/PhoneNumber.java
tag=annotation
-----------

We then need to provide the Constraint implementation.

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/PhoneNumberConstraint.java
tag=constraint
-----------

We also need to include the Constraint on the Composites we want to have them present.

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/DialerComposite.java
tag=composite
-----------

If a Constraint is violated, then a ConstraintViolationException is thrown. The Exception contains ALL violations found
in the method invocation. Concerns can be used to catch and report these violations.

[snippet,java]
----
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/ParameterViolationConcern.java
tag=report
----

== Property Constraint ==

Property Constraints are declared on the Property method.

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/HasPhoneNumber.java
tag=property
-----------

In this case, the Constraint associated with the phoneNumber() method, will be called before the set() method on that
Property is called. If there is a constraint violation, the Exception thrown will be part of the caller, and not the
composite containing the Property, so a reporting constraint on the containing Composite will not see it. If you want
the containing Composite to handle the Constraint Violation, then you need to add a Concern on the Property itself,
which can be done like this;

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/createConstraint/PhoneNumberParameterViolationConcern.java
tag=property
-----------
