View Javadoc
1   /*
2    * (c) Copyright 2013- Openflexo
3    *
4    * This file is part of OpenFlexo.
5    *
6    * OpenFlexo is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * OpenFlexo is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
18   *
19   */
20  
21  package org.openflexo.foundation.doc.fml;
22  
23  import java.util.List;
24  
25  import org.openflexo.connie.DataBinding;
26  import org.openflexo.foundation.doc.FlexoDocFragment;
27  import org.openflexo.foundation.doc.FlexoDocument;
28  import org.openflexo.foundation.doc.TextSelection;
29  import org.openflexo.foundation.fml.FlexoRole;
30  import org.openflexo.foundation.fml.rt.AbstractVirtualModelInstanceModelFactory;
31  import org.openflexo.foundation.fml.rt.FlexoConceptInstance;
32  import org.openflexo.foundation.technologyadapter.TechnologyAdapter;
33  import org.openflexo.pamela.annotations.Adder;
34  import org.openflexo.pamela.annotations.DefineValidationRule;
35  import org.openflexo.pamela.annotations.Embedded;
36  import org.openflexo.pamela.annotations.Getter;
37  import org.openflexo.pamela.annotations.ImplementationClass;
38  import org.openflexo.pamela.annotations.ModelEntity;
39  import org.openflexo.pamela.annotations.PropertyIdentifier;
40  import org.openflexo.pamela.annotations.Remover;
41  import org.openflexo.pamela.annotations.Setter;
42  import org.openflexo.pamela.annotations.XMLAttribute;
43  import org.openflexo.pamela.annotations.XMLElement;
44  import org.openflexo.pamela.annotations.Getter.Cardinality;
45  import org.openflexo.pamela.validation.ValidationError;
46  import org.openflexo.pamela.validation.ValidationIssue;
47  import org.openflexo.pamela.validation.ValidationRule;
48  
49  /**
50   * A role that allows to point on a given {@link FlexoDocFragment} in a {@link FlexoDocument}
51   * 
52   * @author sylvain
53   *
54   * @param <F>
55   *            type of fragment
56   * @param <D>
57   *            type of document in which the fragment resides
58   * @param <TA>
59   *            type of technology adapter
60   */
61  @ModelEntity(isAbstract = true)
62  @ImplementationClass(FlexoFragmentRole.FlexoDocumentFragmentRoleImpl.class)
63  public interface FlexoFragmentRole<F extends FlexoDocFragment<D, TA>, D extends FlexoDocument<D, TA>, TA extends TechnologyAdapter<TA>>
64  		extends FlexoRole<F> {
65  
66  	@PropertyIdentifier(type = TextBinding.class, cardinality = Cardinality.LIST)
67  	public static final String TEXT_BINDINGS_KEY = "textBindings";
68  	@PropertyIdentifier(type = FlexoDocFragment.class)
69  	public static final String FRAGMENT_KEY = "fragment";
70  
71  	public FlexoDocument<D, TA> getDocument();
72  
73  	/**
74  	 * Return the represented fragment in the template resource<br>
75  	 * Note that is not the fragment that is to be managed at run-time
76  	 * 
77  	 * @return
78  	 */
79  	@Getter(value = FRAGMENT_KEY, isStringConvertable = true)
80  	@XMLAttribute
81  	public F getFragment();
82  
83  	/**
84  	 * Sets the represented fragment in the template resource<br>
85  	 * 
86  	 * @param fragment
87  	 */
88  	@Setter(FRAGMENT_KEY)
89  	public void setFragment(F fragment);
90  
91  	@Getter(value = TEXT_BINDINGS_KEY, cardinality = Cardinality.LIST, inverse = TextBinding.FRAGMENT_ROLE_KEY)
92  	@Embedded
93  	@XMLElement
94  	public List<TextBinding<D, TA>> getTextBindings();
95  
96  	@Setter(TEXT_BINDINGS_KEY)
97  	public void setTextBindings(List<TextBinding<D, TA>> someTextBindings);
98  
99  	@Adder(TEXT_BINDINGS_KEY)
100 	public void addToTextBindings(TextBinding<D, TA> aTextBinding);
101 
102 	@Remover(TEXT_BINDINGS_KEY)
103 	public void removeFromTextBindings(TextBinding<D, TA> aTextBinding);
104 
105 	public TextBinding<D, TA> makeTextBinding(TextSelection<D, TA> textSelection, DataBinding<String> binding);
106 
107 	public TextBinding<D, TA> makeTextBinding(TextSelection<D, TA> textSelection, DataBinding<String> binding, boolean isMultiline);
108 
109 	public static abstract class FlexoDocumentFragmentRoleImpl<F extends FlexoDocFragment<D, TA>, D extends FlexoDocument<D, TA>, TA extends TechnologyAdapter<TA>>
110 			extends FlexoRoleImpl<F> implements FlexoFragmentRole<F, D, TA> {
111 
112 		@Override
113 		public FlexoDocument<D, TA> getDocument() {
114 			if (getModelSlot() instanceof FlexoDocumentModelSlot
115 					&& ((FlexoDocumentModelSlot<D>) getModelSlot()).getTemplateResource() != null) {
116 				return ((FlexoDocumentModelSlot<D>) getModelSlot()).getTemplateResource().getDocument();
117 			}
118 			return null;
119 		}
120 
121 		@Override
122 		public TextBinding<D, TA> makeTextBinding(TextSelection<D, TA> textSelection, DataBinding<String> binding) {
123 			return makeTextBinding(textSelection, binding, false);
124 		}
125 
126 		@Override
127 		public TextBinding<D, TA> makeTextBinding(TextSelection<D, TA> textSelection, DataBinding<String> binding, boolean isMultiline) {
128 			TextBinding<D, TA> returned = getFMLModelFactory().newInstance(TextBinding.class);
129 			textSelection.setFragment(getFragment());
130 			returned.setTextSelection(textSelection);
131 			returned.setValue(binding);
132 			returned.setMultiline(isMultiline);
133 			addToTextBindings(returned);
134 			return returned;
135 		}
136 
137 		@Override
138 		public FragmentActorReference<F> makeActorReference(F fragment, FlexoConceptInstance fci) {
139 			AbstractVirtualModelInstanceModelFactory<?> factory = fci.getFactory();
140 			FragmentActorReference<F> returned = factory.newInstance(FragmentActorReference.class);
141 			returned.setFlexoRole(this);
142 			returned.setFlexoConceptInstance(fci);
143 			returned.setModellingElement(fragment);
144 			return returned;
145 		}
146 
147 	}
148 
149 	@DefineValidationRule
150 	public static class FragmentRoleMustAddressATemplateFragment
151 			extends ValidationRule<FragmentRoleMustAddressATemplateFragment, FlexoFragmentRole<?, ?, ?>> {
152 		public FragmentRoleMustAddressATemplateFragment() {
153 			super(FlexoFragmentRole.class, "fragment_role_must_reference_a_template_fragment");
154 		}
155 
156 		@Override
157 		public ValidationIssue<FragmentRoleMustAddressATemplateFragment, FlexoFragmentRole<?, ?, ?>> applyValidation(
158 				FlexoFragmentRole<?, ?, ?> role) {
159 			if (role.getModelSlot() instanceof FlexoDocumentModelSlot
160 					&& ((FlexoDocumentModelSlot<?>) role.getModelSlot()).getTemplateResource() != null) {
161 				if (role.getFragment() == null) {
162 					return new ValidationError<>(this, role, "fragment_role_doesn't_reference_any_template_fragment");
163 				}
164 			}
165 			return null;
166 		}
167 	}
168 
169 }