001    package org.hackystat.sensorbase.resource.sensordatatypes;
002    
003    import org.hackystat.sensorbase.resource.sensorbase.SensorBaseResource;
004    import org.hackystat.sensorbase.resource.sensordatatypes.jaxb.SensorDataType;
005    import org.restlet.Context;
006    import org.restlet.data.MediaType;
007    import org.restlet.data.Request;
008    import org.restlet.data.Response;
009    import org.restlet.data.Status;
010    import org.restlet.resource.Representation;
011    import org.restlet.resource.Variant;
012    
013    /**
014     * Implements a resource for PUT, GET, DELETE of host/sensordatatype/{sensordatatypename}.
015     * @author Philip Johnson
016     */
017    public class SensorDataTypeResource extends SensorBaseResource {
018      
019      /** To be retrieved from the URL. */
020      private String sdtName; 
021      
022      /**
023       * Provides the following representational variants: TEXT_XML.
024       * @param context The context.
025       * @param request The request object.
026       * @param response The response object.
027       */
028      public SensorDataTypeResource(Context context, Request request, Response response) {
029        super(context, request, response);
030        this.sdtName = (String) request.getAttributes().get("sensordatatypename");
031      }
032      
033      /**
034       * Returns the representation of the specified SensorDataType resource.
035       * @param variant The representational variant requested.
036       * @return The representation. 
037       */
038      @Override
039      public Representation represent(Variant variant) {
040        if (!super.sdtManager.hasSdt(this.sdtName)) {
041          getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "Unknown SDT: " + this.sdtName);
042          return null;
043        } 
044        if (variant.getMediaType().equals(MediaType.TEXT_XML)) {
045          String xmlData = super.sdtManager.getSensorDataTypeString(this.sdtName);
046          return super.getStringRepresentation(xmlData);
047        }
048        return null;
049      }
050      
051      /** 
052       * Indicate the PUT method is supported. 
053       * @return True.
054       */
055      @Override
056      public boolean allowPut() {
057          return true;
058      }
059    
060      /**
061       * Implement the PUT method that creates a new SDT. 
062       * <ul>
063       * <li> The XML must be marshallable into an SDT instance using the SDT XmlSchema definition.
064       * <li> The SDT name in the URI string must match the SDT name in the XML.
065       * <li> The authenticated user must be the admin.
066       * </ul>
067       * @param entity The XML representation of the new SDT. 
068       */
069      @Override
070      public void storeRepresentation(Representation entity) {
071        String entityString = null;
072        SensorDataType sdt;
073        if (!validateAuthUserIsAdmin()) {
074          return;
075        }
076    
077        // Try to make the XML payload into an SDT, return failure if this fails. 
078        try { 
079          entityString = entity.getText();
080          sdt = super.sdtManager.makeSensorDataType(entityString);
081        }
082        catch (Exception e) {
083          setStatusMiscError("Bad SensorDataType representation: " + entityString); 
084          return;
085        }
086        
087        try {
088          // Return failure if the URI SdtName is not the same as the XML SdtName.
089          if (!(this.sdtName.equals(sdt.getName()))) {
090            setStatusMiscError("URI SDT name does not equal the representation's name.");
091            return;
092          }
093          // otherwise we add it to the Manager and return success.
094          super.sdtManager.putSdt(sdt);      
095          getResponse().setStatus(Status.SUCCESS_CREATED);
096        }
097        catch (RuntimeException e) {
098          setStatusInternalError(e);
099        }
100      }
101      
102      /** 
103       * Indicate the DELETE method is supported. 
104       * @return True.
105       */
106      @Override
107      public boolean allowDelete() {
108          return true;
109      }
110      
111      /**
112       * Implement the DELETE method that deletes an existing SDT given its name.
113       */
114      @Override
115      public void removeRepresentations() {
116        try {
117          if (!validateAuthUserIsAdmin()) {
118            return;
119          }    
120          super.sdtManager.deleteSdt(sdtName);      
121          getResponse().setStatus(Status.SUCCESS_OK);
122        }
123        catch (RuntimeException e) {
124          setStatusInternalError(e);
125        }
126      }
127    }