8255f5d8d3c9b4fc4f0a455e62e6f412d6f118e1
[vfc/nfvo/wfengine.git] /
1 /*******************************************************************************
2  * Copyright (c) 2012-2013 University of Stuttgart.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * and the Apache License 2.0 which both accompany this distribution,
6  * and are available at http://www.eclipse.org/legal/epl-v10.html
7  * and http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Contributors:
10  *     Oliver Kopp - initial API and implementation
11  *******************************************************************************/
12 package org.eclipse.winery.repository.resources._support.collections.withoutid;
13
14 import java.lang.reflect.Constructor;
15 import java.util.List;
16
17 import javax.ws.rs.Path;
18 import javax.ws.rs.PathParam;
19
20 import org.eclipse.winery.common.Util;
21 import org.eclipse.winery.repository.Utils;
22 import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource;
23 import org.eclipse.winery.repository.resources._support.IPersistable;
24 import org.eclipse.winery.repository.resources._support.collections.EntityCollectionResource;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import com.sun.jersey.api.NotFoundException;
29
30 /**
31  * Class managing a list of entities. It is intended to manage subresources,
32  * where the TOSCA specification did not specify a unique key. Currently, the
33  * hashCode of the XML String representation is used. If other representation
34  * should be used, the method {@code getEntityResource} has to be overriden.
35  * 
36  * @param <EntityResourceT> the resource modeling the entity
37  * @param <EntityT> the entity type of single items in the list
38  */
39 public abstract class EntityWithoutIdCollectionResource<EntityResourceT extends EntityWithoutIdResource<EntityT>, EntityT> extends EntityCollectionResource<EntityResourceT, EntityT> {
40         
41         private static final Logger logger = LoggerFactory.getLogger(EntityWithoutIdCollectionResource.class);
42         
43         
44         /**
45          * {@inheritDoc}
46          */
47         public EntityWithoutIdCollectionResource(Class<EntityResourceT> entityResourceTClazz, Class<EntityT> entityTClazz, List<EntityT> list, IPersistable res) {
48                 super(entityResourceTClazz, entityTClazz, list, res);
49         }
50         
51         /**
52          * Method searching the list for an id with the hashcode instead of
53          * getId(EntityT)
54          */
55         @Override
56         @Path("{id}/")
57         public EntityResourceT getEntityResource(@PathParam("id") String id) {
58                 id = Util.URLdecode(id);
59                 int idInt;
60                 try {
61                         idInt = Integer.parseInt(id);
62                 } catch (java.lang.NumberFormatException e) {
63                         throw new NotFoundException(id + " is not a valid id");
64                 }
65                 EntityT entity = null;
66                 int idx = -1;
67                 for (EntityT c : this.list) {
68                         idx++;
69                         // speed optimization - instead of using getId() we directly use the hash code
70                         int hash = Utils.getXMLAsString(c).hashCode();
71                         if (hash == idInt) {
72                                 entity = c;
73                                 break;
74                         }
75                 }
76                 if (entity == null) {
77                         throw new NotFoundException();
78                 } else {
79                         return this.getEntityResourceInstance(entity, idx);
80                 }
81         }
82         
83         @Override
84         public String getId(EntityT entity) {
85                 return IdDeterminationWithHashCode.INSTANCE.getId(entity);
86         }
87         
88         /**
89          * {@inheritDoc}
90          */
91         @Override
92         protected EntityResourceT getEntityResourceInstance(EntityT entity, int idx) {
93                 Constructor<EntityResourceT> constructor;
94                 try {
95                         constructor = this.entityResourceTClazz.getConstructor(this.entityTClazz, int.class, List.class, AbstractComponentInstanceResource.class);
96                 } catch (Exception e) {
97                         try {
98                                 constructor = this.entityResourceTClazz.getConstructor(this.entityTClazz, int.class, List.class, IPersistable.class);
99                         } catch (NoSuchMethodException | SecurityException e1) {
100                                 EntityWithoutIdCollectionResource.logger.debug("Could not get constructor", e);
101                                 throw new IllegalStateException(e);
102                         }
103                 }
104                 EntityResourceT newInstance;
105                 try {
106                         newInstance = constructor.newInstance(entity, idx, this.list, this.res);
107                 } catch (Exception e) {
108                         EntityWithoutIdCollectionResource.logger.debug("Could not instantiate class", e);
109                         throw new IllegalStateException(e);
110                 }
111                 return newInstance;
112         }
113         
114 }