001package org.andromda.cartridges.spring.metafacades;
002
003import java.util.Collection;
004import org.andromda.metafacades.uml.ClassifierFacade;
005import org.andromda.metafacades.uml.EntityQueryOperation;
006import org.andromda.metafacades.uml.FilteredCollection;
007import org.andromda.metafacades.uml.OperationFacade;
008import org.andromda.metafacades.uml.UMLMetafacadeProperties;
009import org.apache.commons.lang.ObjectUtils;
010import org.apache.commons.lang.StringUtils;
011
012/**
013 * MetafacadeLogic implementation for org.andromda.cartridges.spring.metafacades.SpringManageableEntity.
014 *
015 * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntity
016 */
017public class SpringManageableEntityLogicImpl
018    extends SpringManageableEntityLogic
019{
020    private static final long serialVersionUID = 34L;
021    /**
022     * Public constructor for SpringManageableEntityLogicImpl
023     * @param metaObject
024     * @param context
025     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntity
026     */
027    public SpringManageableEntityLogicImpl (Object metaObject, String context)
028    {
029        super (metaObject, context);
030    }
031
032    /**
033     * @return the configured property denoting the character sequence to use for the separation of namespaces
034     */
035    private String getNamespaceProperty()
036    {
037        return (String)getConfiguredProperty(UMLMetafacadeProperties.NAMESPACE_SEPARATOR);
038    }
039
040    /**
041     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetDaoReferenceName()
042     */
043    protected String handleGetDaoReferenceName()
044    {
045        return StringUtils.uncapitalize(getName()) + "Dao";
046    }
047
048    /**
049     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableDaoName()
050     */
051    protected String handleGetManageableDaoName()
052    {
053        return getName() + "ManageableDao";
054    }
055
056    /**
057     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetFullyQualifiedManageableDaoName()
058     */
059    protected String handleGetFullyQualifiedManageableDaoName()
060    {
061        return getManageablePackageName() + getNamespaceProperty() + getManageableDaoName();
062    }
063
064    /**
065     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableDaoFullPath()
066     */
067    protected String handleGetManageableDaoFullPath()
068    {
069        return StringUtils.replace(this.getFullyQualifiedManageableDaoName(), getNamespaceProperty(), "/");
070    }
071
072    /**
073     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableDaoBaseName()
074     */
075    protected String handleGetManageableDaoBaseName()
076    {
077        return getManageableDaoName() + "Base";
078    }
079
080    /**
081     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetFullyQualifiedManageableDaoBaseName()
082     */
083    protected String handleGetFullyQualifiedManageableDaoBaseName()
084    {
085        return getManageablePackageName() + getNamespaceProperty() + getManageableDaoBaseName();
086    }
087
088    /**
089     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableDaoBaseFullPath()
090     */
091    protected String handleGetManageableDaoBaseFullPath()
092    {
093        return StringUtils.replace(this.getFullyQualifiedManageableDaoBaseName(), this.getNamespaceProperty(), "/");
094    }
095
096    /**
097     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableServiceBaseName()
098     */
099    protected String handleGetManageableServiceBaseName()
100    {
101        return getManageableServiceName() + "Base";
102    }
103
104    /**
105     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetFullyQualifiedManageableServiceBaseName()
106     */
107    protected String handleGetFullyQualifiedManageableServiceBaseName()
108    {
109        return getManageablePackageName() + getNamespaceProperty() + getManageableServiceBaseName();
110    }
111
112    /**
113     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableServiceBaseFullPath()
114     */
115    protected String handleGetManageableServiceBaseFullPath()
116    {
117        return StringUtils.replace(this.getFullyQualifiedManageableServiceBaseName(), this.getNamespaceProperty(), "/");
118    }
119
120    /**
121     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableValueObjectFullPath()
122     */
123    protected String handleGetManageableValueObjectFullPath()
124    {
125        return StringUtils.replace(this.getFullyQualifiedManageableValueObjectName(), this.getNamespaceProperty(), "/");
126    }
127
128    /**
129     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableValueObjectClassName()
130     */
131    protected String handleGetManageableValueObjectClassName()
132    {
133        return getName() + this.getConfiguredProperty(SpringGlobals.CRUD_VALUE_OBJECT_SUFFIX);
134    }
135
136    /**
137     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetFullyQualifiedManageableValueObjectName()
138     */
139    protected String handleGetFullyQualifiedManageableValueObjectName()
140    {
141        return getManageablePackageName() + getNamespaceProperty() + getManageableValueObjectClassName();
142    }
143
144    /**
145     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableSearchExampleFullPath()
146     */
147    protected String handleGetManageableSearchExampleFullPath()
148    {
149        return StringUtils.replace(this.getFullyQualifiedManageableSearchExampleName(), this.getNamespaceProperty(), "/");
150    }
151
152    /**
153     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetManageableSearchExampleClassName()
154     */
155    protected String handleGetManageableSearchExampleClassName()
156    {
157        return getName() + "SearchExample";
158    }
159
160    /**
161     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetFullyQualifiedManageableSearchExampleName()
162     */
163    protected String handleGetFullyQualifiedManageableSearchExampleName()
164    {
165        return getManageablePackageName() + getNamespaceProperty() + getManageableSearchExampleClassName();
166    }
167
168    /**
169     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleIsRemotingTypeRmi()
170     */
171    protected boolean handleIsRemotingTypeRmi()
172    {
173        return SpringGlobals.REMOTING_PROTOCOL_RMI.equalsIgnoreCase(this.getRemotingType());
174    }
175
176    /**
177     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleIsRemotingTypeNone()
178     */
179    protected boolean handleIsRemotingTypeNone()
180    {
181        return SpringGlobals.REMOTING_PROTOCOL_NONE.equalsIgnoreCase(this.getRemotingType());
182    }
183
184    /**
185     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleIsRemotingTypeHttpInvoker()
186     */
187    protected boolean handleIsRemotingTypeHttpInvoker()
188    {
189        return SpringGlobals.REMOTING_PROTOCOL_HTTPINVOKER.equalsIgnoreCase(this.getRemotingType());
190    }
191
192    /**
193     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleIsRemotingTypeHessian()
194     */
195    protected boolean handleIsRemotingTypeHessian()
196    {
197        return SpringGlobals.REMOTING_PROTOCOL_HESSIAN.equalsIgnoreCase(this.getRemotingType());
198    }
199
200    /**
201     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleIsRemotingTypeBurlap()
202     */
203    protected boolean handleIsRemotingTypeBurlap()
204    {
205        return SpringGlobals.REMOTING_PROTOCOL_BURLAP.equalsIgnoreCase(this.getRemotingType());
206    }
207
208    /**
209     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetRemoteUrl()
210     */
211    protected String handleGetRemoteUrl()
212    {
213        final StringBuilder result = new StringBuilder();
214
215        String propertyPrefix = ObjectUtils.toString(this.getConfiguredProperty(SpringGlobals.CONFIG_PROPERTY_PREFIX));
216
217        if (this.isRemotingTypeNone())
218        {
219            // nothing
220        }
221        else if (this.isRemotingTypeHttpInvoker() || this.isRemotingTypeHessian() || this.isRemotingTypeBurlap())
222        {
223            // server
224            result.append("${").append(propertyPrefix).append("remoteHttpScheme}://${");
225            result.append(propertyPrefix);
226            result.append("remoteServer}");
227
228            // port
229            if (hasServiceRemotePort())
230            {
231                result.append(":${");
232                result.append(propertyPrefix);
233                result.append("remotePort}");
234            }
235
236            // context
237            if (hasServiceRemoteContext())
238            {
239                result.append("/${");
240                result.append(propertyPrefix);
241                result.append("remoteContext}");
242            }
243
244            // service name
245            result.append("/remote");
246            result.append(this.getManageableServiceName());
247        }
248        else if (this.isRemotingTypeRmi())
249        {
250            // server
251            result.append("${").append(propertyPrefix).append("remoteRmiScheme}://${");
252            result.append(propertyPrefix);
253            result.append("remoteServer}");
254
255            // port
256            if (hasServiceRemotePort())
257            {
258                result.append(":${");
259                result.append(propertyPrefix);
260                result.append("remotePort}");
261            }
262
263            // service name
264            result.append("/remote");
265            result.append(this.getManageableServiceName());
266        }
267
268        return result.toString();
269    }
270
271    /**
272     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetRemoteServer()
273     */
274    protected String handleGetRemoteServer()
275    {
276        return StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty(SpringGlobals.SERVICE_REMOTE_SERVER)));
277    }
278
279    /**
280     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetRemotePort()
281     */
282    protected String handleGetRemotePort()
283    {
284        final String serviceRemotePort =
285            StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty(SpringGlobals.SERVICE_REMOTE_PORT)));
286        return SpringMetafacadeUtils.getServiceRemotePort(this, serviceRemotePort);
287    }
288
289    /**
290     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleGetRemoteContext()
291     */
292    protected String handleGetRemoteContext()
293    {
294        return this.isConfiguredProperty(SpringGlobals.SERVICE_REMOTE_CONTEXT)
295            ? ObjectUtils.toString(this.getConfiguredProperty(SpringGlobals.SERVICE_REMOTE_CONTEXT)) : "";
296    }
297
298    /**
299     * @see org.andromda.cartridges.spring.metafacades.SpringManageableEntityLogic#handleIsRemotable()
300     */
301    protected boolean handleIsRemotable()
302    {
303        return !this.isRemotingTypeNone();
304    }
305
306    /**
307     * Gets the remoting type for this service.
308     */
309    private String getRemotingType()
310    {
311        final String serviceRemotingType =
312            StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty(SpringGlobals.SERVICE_REMOTING_TYPE)));
313        return SpringMetafacadeUtils.getServiceRemotingType(this, serviceRemotingType);
314    }
315
316    /**
317     * Checks whether this service has a remote port assigned.
318     *
319     * @return <code>true</code> if the service has a remote port, <code>false</code> otherwise.
320     */
321    private boolean hasServiceRemotePort()
322    {
323        return StringUtils.isNotBlank(this.getRemotePort());
324    }
325
326    /**
327     * Checks whether the service has a remote context assigned.
328     *
329     * @return <code>true</code> if the service has a remote context, <code>false</code> otherweise.
330     */
331    private boolean hasServiceRemoteContext()
332    {
333        return StringUtils.isNotBlank(this.getRemoteContext());
334    }
335    
336    /**
337     * Only allow business operations returning the entity or instances of the id type 
338     *
339     * @return Allowed business operations.
340     */
341    public Collection<SpringEntityOperation> getManageableDaoBusinessOperations()
342    {
343        Collection<SpringEntityOperation> result=super.getDaoBusinessOperations();
344        result = new FilteredCollection<SpringEntityOperation>(result)
345        {
346            private static final long serialVersionUID = 34L;
347            public boolean evaluate(Object object)
348            {
349                final SpringEntityOperation operation=(SpringEntityOperation)object;
350                final ClassifierFacade returnType=operation.getReturnType();
351                return operation.getVisibility().equals("public") &&
352                       (returnType.isDataType() ||
353                        returnType.getFullyQualifiedName().equals(getFullyQualifiedName()));
354            }
355        };
356
357        return result;
358    }
359
360    /**
361     * Only allow query operations returning the entity
362     *
363     * @return Allowed query operations.
364     */
365    public Collection<EntityQueryOperation> getManageableQueryOperations()
366    {
367        Collection<EntityQueryOperation> result=super.getQueryOperations();
368        result = new FilteredCollection<EntityQueryOperation>(result)
369        {
370            private static final long serialVersionUID = 34L;
371            public boolean evaluate(Object object)
372            {
373                final EntityQueryOperation operation=(EntityQueryOperation)object;
374                final ClassifierFacade returnType=operation.getReturnType();
375                return operation.getVisibility().equals("public") &&
376                       (returnType.isDataType() ||
377                        returnType.getFullyQualifiedName().equals(getFullyQualifiedName()));
378            }
379        };
380        return result;
381    }
382 
383    /**
384     * Helper function TRUE when operation upperBound > 1
385     * TODO Check Operation return type upper bound also
386     * @param operation 
387     * @return true if the operation returns a collection
388     */
389    public boolean isCollection(OperationFacade operation)
390    {
391        return (operation.getUpper() > 1 || operation.getUpper() == -1);
392    }
393}