001    package org.hackystat.dailyprojectdata.resource.unittest;
002    
003    import static org.hackystat.dailyprojectdata.server.ServerProperties.SENSORBASE_FULLHOST_KEY;
004    
005    import java.io.StringWriter;
006    import java.util.logging.Logger;
007    
008    import javax.xml.bind.JAXBContext;
009    import javax.xml.bind.Marshaller;
010    import javax.xml.datatype.XMLGregorianCalendar;
011    import javax.xml.parsers.DocumentBuilder;
012    import javax.xml.parsers.DocumentBuilderFactory;
013    import javax.xml.transform.Transformer;
014    import javax.xml.transform.TransformerFactory;
015    import javax.xml.transform.dom.DOMSource;
016    import javax.xml.transform.stream.StreamResult;
017    
018    import org.hackystat.dailyprojectdata.resource.dailyprojectdata.DailyProjectDataResource;
019    import org.hackystat.dailyprojectdata.resource.unittest.jaxb.MemberData;
020    import org.hackystat.dailyprojectdata.resource.unittest.jaxb.UnitTestDailyProjectData;
021    import org.hackystat.sensorbase.client.SensorBaseClient;
022    import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataIndex;
023    import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataRef;
024    import org.hackystat.utilities.tstamp.Tstamp;
025    import org.restlet.Context;
026    import org.restlet.data.MediaType;
027    import org.restlet.data.Request;
028    import org.restlet.data.Response;
029    import org.restlet.resource.Representation;
030    import org.restlet.resource.Variant;
031    import org.w3c.dom.Document;
032    
033    /**
034     * Implements the Resource for processing GET {host}/unittest/{user}/{projectname}/{timestamp}
035     * requests. 
036     * 
037     * Authenticated user must be the uriUser, or Admin, or project member. 
038     * 
039     * @author Pavel Senin, Philip Johnson
040     */
041    
042    public class UnitTestResource extends DailyProjectDataResource {
043    
044      /**
045       * The standard constructor.
046       * 
047       * @param context The context.
048       * @param request The request object.
049       * @param response The response object.
050       */
051      public UnitTestResource(Context context, Request request, Response response) {
052        super(context, request, response);
053      }
054    
055      /**
056       * Returns an UnitTestDailyProjectData instance.
057       * 
058       * @param variant The representational variant requested.
059       * @return The representation.
060       */
061      @Override
062      public Representation represent(Variant variant) {
063        Logger logger = this.server.getLogger();
064        logger.fine("UnitTest DPD: Starting");
065        if (variant.getMediaType().equals(MediaType.TEXT_XML)) {
066          try {
067            // [1] get the SensorBaseClient for the user making this request.
068            SensorBaseClient client = super.getSensorBaseClient();
069            // [2] Check the front side cache and return if the DPD is found and is OK to access.
070            String cachedDpd = this.server.getFrontSideCache().get(uriUser, project, uriString);
071            if ((cachedDpd != null) && client.inProject(uriUser, project)) {
072              return super.getStringRepresentation(cachedDpd);
073            }
074            // [2] get a SensorDataIndex of UnitTest sensor data for this Project on the requested day.
075            XMLGregorianCalendar startTime = Tstamp.makeTimestamp(this.timestamp);
076            XMLGregorianCalendar endTime = Tstamp.incrementDays(startTime, 1);
077            logger.fine("UnitTest DPD: Requesting index: " + uriUser + " " + project);
078            SensorDataIndex index = client.getProjectSensorData(uriUser, project, startTime, endTime,
079                "UnitTest");
080            // [3] Update the counter with this data.
081            logger.fine("UnitTest DPD: Got index.  " + index.getSensorDataRef().size() + " instances");
082            UnitTestCounter counter = new UnitTestCounter();
083            for (SensorDataRef ref : index.getSensorDataRef()) {
084              counter.add(client.getSensorData(ref));
085            } 
086            logger.fine("UnitTest DPD: Finished retrieving instances. "); 
087    
088            // return resulting data
089            UnitTestDailyProjectData unitTestDPD = new UnitTestDailyProjectData();
090            // create the individual MemberData elements.
091            String sensorBaseHost = this.server.getServerProperties().get(SENSORBASE_FULLHOST_KEY);
092            for (String member : counter.getMembers()) {
093              MemberData memberData = new MemberData();
094              memberData.setMemberUri(sensorBaseHost + "users/" + member);
095              memberData.setSuccess(counter.getPassCount(member));
096              memberData.setFailure(counter.getFailCount(member));
097              unitTestDPD.getMemberData().add(memberData);
098            }
099    
100            unitTestDPD.setOwner(uriUser);
101            unitTestDPD.setProject(project);
102            unitTestDPD.setStartTime(startTime);
103            unitTestDPD.setUriPattern("**"); // we don't support UriPatterns yet.
104    
105            String xmlData = makeUnitTestDPD(unitTestDPD);
106            if (!Tstamp.isTodayOrLater(startTime)) {
107              this.server.getFrontSideCache().put(uriUser, project, uriString, xmlData);
108            }
109            logRequest("UnitTest");
110            return super.getStringRepresentation(xmlData);
111    
112          }
113          catch (Exception e) {
114            setStatusError("Error creating UnitTest DPD.", e);
115            return null;
116          }
117        }
118        return null;
119      }
120    
121      /**
122       * Returns the passed UnitTestDPD instance as a String encoding of its XML representation.
123       * 
124       * @param data The UnitTestDPD instance.
125       * @return The XML String representation.
126       * @throws Exception If problems occur during translation.
127       */
128      private String makeUnitTestDPD(UnitTestDailyProjectData data) throws Exception {
129        JAXBContext unitTestJAXB = (JAXBContext) this.server.getContext().getAttributes().get(
130            "UnitTestJAXB");
131        Marshaller marshaller = unitTestJAXB.createMarshaller();
132        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
133        dbf.setNamespaceAware(true);
134        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
135        Document doc = documentBuilder.newDocument();
136        marshaller.marshal(data, doc);
137        DOMSource domSource = new DOMSource(doc);
138        StringWriter writer = new StringWriter();
139        StreamResult result = new StreamResult(writer);
140        TransformerFactory tf = TransformerFactory.newInstance();
141        Transformer transformer = tf.newTransformer();
142        transformer.transform(domSource, result);
143        return writer.toString();
144      }
145    }