Back to project page dissertation-project.
The source code is released under:
MIT License
If you think the Android project dissertation-project listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.fyp.widerst.backend; /* ww w.j av a2s . c o m*/ import static com.fyp.widerst.WiderstObjectifyService.ofy; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fyp.widerst.Constants; import com.fyp.widerst.entity.DataPiece; import com.fyp.widerst.entity.DataWhole; import com.fyp.widerst.util.GcmHelper; import com.google.appengine.api.LifecycleManager; import com.google.appengine.api.LifecycleManager.ShutdownHook; import com.google.appengine.api.blobstore.BlobstoreInputStream; import com.google.appengine.api.blobstore.BlobstoreService; import com.google.appengine.api.blobstore.BlobstoreServiceFactory; import com.google.appengine.api.files.AppEngineFile; import com.google.appengine.api.files.FileService; import com.google.appengine.api.files.FileServiceFactory; import com.google.appengine.api.files.FileWriteChannel; import com.googlecode.objectify.Key; import com.googlecode.objectify.Work; @SuppressWarnings("serial") public class FileJoinerBackend extends HttpServlet { private static final Logger logger = Logger.getLogger(FileJoinerBackend.class.getName()); /* Requires Instance-level access due to Transaction inner class */ private DataWhole dataWhole = null; private Map<Key<DataPiece>, DataPiece> dataPieces; @Override /** * */ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { setLifecycleManager(); /* Query the DataWhole that requires re-structuring */ final String dwKeyString = req.getParameter(Constants.DATAWHOLE_KEY_PARAM); if (null == dwKeyString) { resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); logger.log(Level.WARNING, "DataWhole Key is NULL!"); return; } logger.log(Level.WARNING, "DataWhole Key is " + dwKeyString); Boolean transaction = ofy().transact(new Work<Boolean>() { @Override public Boolean run() { dataWhole = ofy().load().type(DataWhole.class).id(dwKeyString).get(); if (null != dataWhole) { if (null == dataWhole.getBlobKey()) { if (dataWhole.getDataPieceKeyList().size() == dataWhole.getNumOfPieces()) { return true; } } else { return true; } } logger.log(Level.SEVERE, "DataWhole NOT found!"); return false; } }); /* Check if an interrupt has been called */ if (Thread.interrupted()) { return; } if (transaction) { if (structureFileAndPostToDb()) { GcmHelper.sendWholeCompletionNotification(dataWhole); resp.setStatus(HttpServletResponse.SC_OK); } else { resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } else { resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); } } /** * @return * @throws IOException */ private boolean structureFileAndPostToDb() throws IOException { /* Define the File API specific instances */ BlobstoreService blobStoreService = BlobstoreServiceFactory.getBlobstoreService(); FileService fileService = FileServiceFactory.getFileService(); /* */ final AppEngineFile blobFile = fileService.createNewBlobFile(dataWhole.getMimeType(), dataWhole.getFileName()); /* */ final FileWriteChannel writeChannel = fileService.openWriteChannel(blobFile, true); /* */ Boolean transaction = ofy().transact(new Work<Boolean>() { @Override public Boolean run() { dataPieces = ofy().load().keys(dataWhole.getDataPieceKeyList()); return dataPieces.size() > 0 ? true : false; } }); if (transaction) { int length; byte[] buffer = new byte[1024000]; for (int i = 1; i <= dataPieces.size(); i++) { Key<DataPiece> pieceKey = Key.create(Key.create(DataWhole.class, dataWhole.getKey()), DataPiece.class, dataWhole.getKey() + i); DataPiece dataPiece = dataPieces.get(pieceKey); logger.log(Level.INFO, "DataPiece Blobkey is " + dataPiece.getBlobKey()); BlobstoreInputStream blobStream = new BlobstoreInputStream(dataPiece.getBlobKey()); while ((length = blobStream.read(buffer)) != -1) { writeChannel.write(ByteBuffer.wrap(buffer, 0, length)); } blobStream.close(); blobStoreService.delete(dataPiece.getBlobKey()); } writeChannel.closeFinally(); dataWhole.setBlobKey(fileService.getBlobKey(blobFile)); logger.log(Level.INFO, "New Blobkey is " + fileService.getBlobKey(blobFile)); /* Remove the pieces once it has been successfully restructured */ for (DataPiece piece : dataPieces.values()) { blobStoreService.delete(piece.getBlobKey()); } Boolean dwTransaction = ofy().transact(new Work<Boolean>() { @Override public Boolean run() { /* Persist the modified DataWhole */ dataWhole.setDataPieceKeyList(new ArrayList<Key<DataPiece>>()); ofy().save().entity(dataWhole).now(); /* Remove the DataWhole's children */ ofy().delete().entities(dataPieces.values()).now(); return true; } }); return dwTransaction; } return false; } /** * */ private void setLifecycleManager() { /* Specify the lifecycle manager to be used */ LifecycleManager.getInstance().setShutdownHook(new ShutdownHook() { @Override public void shutdown() { /* * Calls interrupt on all threads within this instance. * Therefore, periodic checks must be make to ensure this * instance hasn't been told to shutdown. */ LifecycleManager.getInstance().interruptAllRequests(); } }); } }