Examples of StorageObject


Examples of org.jets3t.service.model.StorageObject

                    // Invoke lazy upload object creator.
                    int maxBatchSize = Math.min(uploadBatchSize, objectsToUpload.size());
                    for (int i = 0; i < maxBatchSize; i++) {
                        LazyPreparedUploadObject lazyObj = objectsToUpload.remove(0);
                        StorageObject object = null;

                        try {
                            object = lazyObj.prepareUploadObject();
                        } catch (FileNotFoundException e) {
                            if (skipMissingFiles) {
                                printOutputLine(
                                    "WARNING: Skipping unreadable file: "
                                    + lazyObj.getFile().getAbsolutePath(),
                                    REPORT_LEVEL_NONE);
                                continue;
                            } else {
                                throw e;
                            }
                        }

                        if (multipartUtils != null
                            && multipartUtils.isFileLargerThanMaxPartSize(lazyObj.getFile()))
                        {
                            objectsForMultipartUpload.add(object);
                        } else {
                            objectsForStandardPut.add(object);
                        }
                    }

                    // Perform standard object uploads
                    if (objectsForStandardPut.size() > 0) {
                        (new ThreadedStorageService(storageService, serviceEventAdaptor)).putObjects(
                            bucket.getName(), objectsForStandardPut.toArray(new StorageObject[] {}));
                        serviceEventAdaptor.throwErrorIfPresent();
                    }

                    // Perform multipart uploads
                    if (objectsForMultipartUpload.size() > 0) {
                        multipartUtils.uploadObjects(
                            bucket.getName(), (S3Service)storageService,
                            objectsForMultipartUpload, serviceEventAdaptor);
                    }
                }
            } while (objectKeyIter.hasNext()); // End of upload loop

        } while (priorLastKey != null); // End of list and upload loop

        // Delete objects that don't correspond with local files.
        List<StorageObject> objectsToDelete = new ArrayList<StorageObject>();
        Iterator<String> serverOnlyIter = mergedDiscrepancyResults.onlyOnServerKeys.iterator();
        while (serverOnlyIter.hasNext()) {
            // Relative key
            String relativeKeyPath = serverOnlyIter.next();

            // Build absolute key path for object.
            String targetKey = relativeKeyPath;
            if (rootObjectPath.length() > 0) {
                if (rootObjectPath.endsWith(Constants.FILE_PATH_DELIM)) {
                    targetKey = rootObjectPath + targetKey;
                } else {
                    targetKey = rootObjectPath + Constants.FILE_PATH_DELIM + targetKey;
                }
            }
            StorageObject object = new StorageObject(targetKey);

            if (isKeepFiles || isNoDelete) {
                printOutputLine("d " + relativeKeyPath, REPORT_LEVEL_DIFFERENCES);
            } else {
                printOutputLine("D " + relativeKeyPath, REPORT_LEVEL_ACTIONS);
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

            // Optionally download objects in batches to minimize memory use
            do {
                List<DownloadPackage> downloadPackagesList = new ArrayList<DownloadPackage>();
                while (objectKeyIter.hasNext()) {
                    String keyPath = objectKeyIter.next();
                    StorageObject object = objectsMap.get(keyPath);
                    String localPath = keyPath;

                    // If object metadata is not available, skip zero-byte objects that
                    // are not definitively directory place-holders, since we can't tell
                    // whether they are directory place-holders or normal empty files.
                    if (!object.isMetadataComplete()
                        && object.getContentLength() == 0
                        && !object.isDirectoryPlaceholder())
                    {
                        continue;
                    }

                    File fileTarget = new File(localDirectory, keyPath);
                    // Create local directories corresponding to objects flagged as dirs.
                    if (object.isDirectoryPlaceholder()) {
                        localPath = ObjectUtils.convertDirPlaceholderKeyNameToDirName(keyPath);
                        fileTarget = new File(localDirectory, localPath);
                        if (doAction) {
                            fileTarget.mkdirs();
                        }
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

            this.aclString = aclString;
            this.encryptionUtil = encryptionUtil;
        }

        public StorageObject prepareUploadObject() throws Exception {
            StorageObject newObject = ObjectUtils.createObjectForUpload(
                targetKey, file, md5HashOfFile, encryptionUtil, isGzipEnabled, null);

            if ("PUBLIC_READ".equalsIgnoreCase(aclString)) {
                newObject.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
            } else if ("PUBLIC_READ_WRITE".equalsIgnoreCase(aclString)) {
                newObject.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ_WRITE);
            } else if ("PRIVATE".equalsIgnoreCase(aclString)) {
                // Private is the default, no need to add an ACL
            } else {
                throw new Exception("Invalid value for ACL string: " + aclString);
            }

            // Apply custom metadata items to upload object.
            newObject.addAllMetadata(customMetadata);

            return newObject;
        }
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

        assertFalse(ServiceUtils.isEtagAlsoAnMD5Hash(
            "cb8aaa4056eb349af16b1907280dee18cb"));
    }

    public void testMd5ETag() throws Exception {
        StorageObject so = new S3Object("");

        // MD5 ETag values
        so.setETag("cb8aaa4056eb349af16b1907280dee18");
        assertEquals("y4qqQFbrNJrxaxkHKA3uGA==", so.getMd5HashAsBase64());
    }
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

        so.setETag("cb8aaa4056eb349af16b1907280dee18");
        assertEquals("y4qqQFbrNJrxaxkHKA3uGA==", so.getMd5HashAsBase64());
    }

    public void testNonMd5ETag() throws Exception {
        StorageObject so = new S3Object("");

        so.setETag("cb8aaa4056eb349af16b1907280dee18-1");
        assertEquals(null, so.getMd5HashAsBase64());

        so.setETag("cb8aaa4056eb349af16b1907280dee");
        assertEquals(null, so.getMd5HashAsBase64());

        so.setETag("cb8aaa4056eb349af16b1907280dee1");
        assertEquals(null, so.getMd5HashAsBase64());

        so.setETag("cb8aaa4056eb349af16b1907280dee18cb");
        assertEquals(null, so.getMd5HashAsBase64());

        so.setETag("12345");
        String hash = so.getMd5HashAsBase64();
        assertEquals(null, hash);

        so.setETag("123456-7");
        hash = so.getMd5HashAsBase64();
        assertEquals(null, hash);
    }
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

            segFIS.close();
        }
    }

    public void testCaseInsensitiveObjectMetadataNames() {
        StorageObject obj = new StorageObject("SomeName");

        // Get metadata names, case-insensitive
        obj.addMetadata("My-name", "1");
        assertEquals("1", obj.getMetadata("My-name"));
        assertEquals("1", obj.getMetadata("My-Name"));
        assertEquals("1", obj.getMetadata("my-name"));

        assertNull(obj.getMetadata(null));

        // Check for presense of metadata, case-insensitive
        assertTrue(obj.containsMetadata("My-name"));
        assertTrue(obj.containsMetadata("My-Name"));
        assertTrue(obj.containsMetadata("my-name"));

        // New item with same case-insensitive name replaces old value
        obj.addMetadata("My-Name", "2");
        assertEquals("2", obj.getMetadata("My-name"));
        assertEquals("2", obj.getMetadata("My-Name"));
        assertEquals("2", obj.getMetadata("my-name"));

        // Null metadata names are allowed (though a bad idea...)
        obj.addMetadata(null, "3");
        assertEquals("3", obj.getMetadata(null));
        obj.addMetadata(null, "4");
        assertEquals("4", obj.getMetadata(null));

        // Last add operation with matching case-insensitive name wins
        obj.addMetadata("CaseInsensitive", "5");
        obj.addMetadata("Caseinsensitive", "6");
        obj.addMetadata("caseinsensitive", "7");
        obj.addMetadata("CASEINSENSITIVE", "8");
        assertEquals("8", obj.getMetadata("CaseInsensitive"));

        // Remove item is also case-insensitive
        assertEquals(3, obj.getMetadataMap().size()); // Items added so far
        obj.removeMetadata("my-namE");
        obj.removeMetadata(null);
        obj.removeMetadata("CASEinsensitive");

        // Add all
        Map<String, Object> newMetadata = new HashMap<String, Object>();
        newMetadata.put("FIRST", "1st");
        newMetadata.put("second", "2nd");
        newMetadata.put("thIrd", "3rd");
        obj.addAllMetadata(newMetadata);
        assertEquals("1st", obj.getMetadata("first"));
        assertEquals("2nd", obj.getMetadata("SECOND"));
        assertEquals("3rd", obj.getMetadata("THiRD"));

        // Replace all
        newMetadata = new HashMap<String, Object>();
        newMetadata.put("one", "1st");
        newMetadata.put("TWO", "2nd");
        newMetadata.put("THRee", "3rd");
        obj.replaceAllMetadata(newMetadata);
        assertEquals(3, obj.getMetadataMap().size());
        assertEquals("1st", obj.getMetadata("ONE"));
        assertEquals("2nd", obj.getMetadata("two"));
        assertEquals("3rd", obj.getMetadata("thrEE"));
    }
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

            // Put the object in S3 using the signed URL (no AWS credentials required)
            RestS3Service restS3Service = new RestS3Service(null);
            restS3Service.putObjectWithSignedUrl(signedPutUrl, object);

            // Ensure the object was created.
            StorageObject objects[] = service.listObjects(bucketName, object.getKey(), null);
            assertEquals("Signed PUT URL failed to put/create object", objects.length, 1);

            // Change the object's content-type and ensure the signed PUT URL disallows the put.
            object.setContentType("application/octet-stream");
            try {
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

                testDataOverLimit[i] = (byte) (i % 256);
            }

            // Confirm that non-file-based objects are not accepted
            try {
                StorageObject myObject = new StorageObject();
                service.putObjectMaybeAsMultipart(bucketName, myObject, fiveMB);
                fail("");
            } catch (ServiceException se) {
            }

            // Create file for testing
            File testDataFile = File.createTempFile("JetS3t-testMultipartUploadWithConvenienceMethod", ".txt");
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(testDataFile));
            bos.write(testDataOverLimit);
            bos.close();
            testDataOverLimit = null; // Free up a some memory

            // Setup non-canned ACL
            AccessControlList testACL = buildAccessControlList();
            testACL.setOwner(service.getAccountOwner());
            testACL.grantPermission(GroupGrantee.AUTHENTICATED_USERS, Permission.PERMISSION_READ);

            // Setup file-based object
            StorageObject objectViaConvenienceMethod = new StorageObject(testDataFile);
            objectViaConvenienceMethod.setKey("multipart-object-via-convenience-method.txt");
            objectViaConvenienceMethod.addMetadata("my-metadata", "convenient? yes!");
            objectViaConvenienceMethod.setAcl(testACL);
            objectViaConvenienceMethod.setStorageClass(S3Object.STORAGE_CLASS_REDUCED_REDUNDANCY);

            // Upload object
            service.putObjectMaybeAsMultipart(bucketName, objectViaConvenienceMethod, fiveMB);

            // Confirm completed object exists and has expected metadata
            objectViaConvenienceMethod = service.getObjectDetails(
                bucketName, objectViaConvenienceMethod.getKey());
            assertEquals(
                "convenient? yes!",
                objectViaConvenienceMethod.getMetadata("my-metadata"));

            // Confirm custom ACL was applied automatically
            AccessControlList aclViaConvenienceMethod = service.getObjectAcl(
                bucketName, objectViaConvenienceMethod.getKey());
            assertEquals(
                testACL.getPermissionsForGrantee(GroupGrantee.AUTHENTICATED_USERS),
                aclViaConvenienceMethod.getPermissionsForGrantee(GroupGrantee.AUTHENTICATED_USERS));

            // Confirm completed object was indeed uploaded as a multipart upload,
            // not a standard PUT (ETag is not a valid MD5 hash in this case)
            assertFalse(ServiceUtils.isEtagAlsoAnMD5Hash(
                objectViaConvenienceMethod.getETag()));

            /*
             * Perform a threaded multipart upload
             */
            String objectKeyForThreaded = "threaded-multipart-object.txt";
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

            // Create a normal object
            S3Object object = new S3Object("unencrypted-object", "Some data");
            object.setServerSideEncryptionAlgorithm(S3Object.SERVER_SIDE_ENCRYPTION__NONE);
            s3Service.putObject(bucketName, object);
            // Confirm object is not encrypted
            StorageObject objDetails = s3Service.getObjectDetails(bucketName, object.getKey());
            assertEquals(null, objDetails.getServerSideEncryptionAlgorithm());

            // Fail to create an encrypted object, due to invalid algorithm
            object = new S3Object("failed-encrypted-object", "Some data");
            object.setServerSideEncryptionAlgorithm("AES999");
            try {
                s3Service.putObject(bucketName, object);
                fail("Expected error about invalid server-side encryption algorithm");
            } catch (S3ServiceException e) {
                assertEquals("InvalidArgument", e.getErrorCode());
            }

            // Create an encrypted object, set explicitly
            object = new S3Object("encrypted-object", "Some data");
            object.setServerSideEncryptionAlgorithm(S3Object.SERVER_SIDE_ENCRYPTION__AES256);
            s3Service.putObject(bucketName, object);
            // Confirm object is encrypted
            objDetails = s3Service.getObjectDetails(bucketName, object.getKey());
            assertEquals(S3Object.SERVER_SIDE_ENCRYPTION__AES256, objDetails.getMetadata("server-side-encryption"));
            assertEquals(S3Object.SERVER_SIDE_ENCRYPTION__AES256, objDetails.getServerSideEncryptionAlgorithm());

            // Create an encrypted object, per default algorithm set in service properties
            Jets3tProperties properties = new Jets3tProperties();
            properties.setProperty("s3service.server-side-encryption",
                S3Object.SERVER_SIDE_ENCRYPTION__AES256);
            s3Service = (S3Service) getStorageService(getCredentials(), properties);
            object = new S3Object("encrypted-object-as-default", "Some data");
            s3Service.putObject(bucketName, object);
            // Confirm object is encrypted
            objDetails = s3Service.getObjectDetails(bucketName, object.getKey());
            assertEquals(S3Object.SERVER_SIDE_ENCRYPTION__AES256, objDetails.getMetadata("server-side-encryption"));
            assertEquals(S3Object.SERVER_SIDE_ENCRYPTION__AES256, objDetails.getServerSideEncryptionAlgorithm());

        } finally {
            cleanupBucketForTest("testServerSideEncryption");
        }
    }
View Full Code Here

Examples of org.jets3t.service.model.StorageObject

    public void testObjectManagement() throws Exception {
        String bucketName = createBucketForTest("testObjectManagement").getName();
        RestStorageService service = getStorageService(getCredentials());

        try {
            StorageObject object = new StorageObject("TestObject");

            try {
                service.putObject((String) null, null);
                fail("Cannot create an object without a valid bucket");
            } catch (ServiceException e) {
            }

            try {
                service.putObject((String) null, object);
                fail("Cannot create an object without a valid bucket");
            } catch (ServiceException e) {
            }

            try {
                service.putObject(bucketName, new StorageObject());
                fail("Cannot create an object without a valid object");
            } catch (ServiceException e) {
            }

            // Create basic object with no content type (use the default) and no data.
            StorageObject basicObject = service.putObject(bucketName, object);

            // Ensure Content-Type is set to binary by default
            // TODO: Google Storage bug: Content type returned on initial PUT is always "text/html"
            if (!TARGET_SERVICE_GS.equals(getTargetService())) {
                assertTrue("Unexpected default content type",
                    Mimetypes.MIMETYPE_OCTET_STREAM.equals(basicObject.getContentType()));
            }

            // Re-retrieve object to ensure it was correctly created.
            basicObject = service.getObject(bucketName, object.getKey());
            assertEquals("Unexpected content type",
                Mimetypes.MIMETYPE_OCTET_STREAM, basicObject.getContentType());
            assertEquals("Unexpected size for 'empty' object", 0, basicObject.getContentLength());
            basicObject.closeDataInputStream();

            // Make sure bucket cannot be removed while it has contents.
            try {
                service.deleteBucket(bucketName);
                fail("Should not be able to delete a bucket containing objects");
            } catch (ServiceException e) {
            }

            // Update/overwrite object with real data content and some metadata.
            String contentType = "text/plain";
            String objectData = "Just some rubbish text to include as data";
            String dataMd5HashAsHex = ServiceUtils.toHex(
                ServiceUtils.computeMD5Hash(objectData.getBytes()));
            HashMap<String, Object> metadata = new HashMap<String, Object>();
            metadata.put("creator", "testObjectManagement");
            metadata.put("purpose", "For testing purposes");
            object.replaceAllMetadata(metadata);
            object.setContentType(contentType);
            object.setDataInputStream(new ByteArrayInputStream(objectData.getBytes()));
            StorageObject dataObject = service.putObject(bucketName, object);
            // TODO: Google Storage bug: Content type returned on initial PUT is always "text/html"
            if (TARGET_SERVICE_GS.equals(getTargetService())) {
                dataObject = service.getObject(bucketName, object.getKey());
            }
            assertEquals("Unexpected content type", contentType, dataObject.getContentType());
            assertEquals("Mismatching MD5 hex hash", dataMd5HashAsHex, dataObject.getETag());

            // Retrieve data object to ensure it was correctly created, the server-side hash matches
            // what we expect, and we get our metadata back.
            dataObject = service.getObject(bucketName, object.getKey());
            assertEquals("Unexpected default content type", "text/plain", dataObject.getContentType());
            // TODO: Google Storage doesn't reliably return Content-Length in a GET
            if (!TARGET_SERVICE_GS.equals(getTargetService())) {
                assertEquals("Unexpected content-length for object",
                    objectData.length(), dataObject.getContentLength());
            }
            assertEquals("Mismatching hash", dataMd5HashAsHex, dataObject.getETag());

            // Check user's data are available in basic metadata map
            assertEquals("Missing creator metadata", "testObjectManagement",
                dataObject.getMetadata("creator"));
            assertEquals("Missing purpose metadata", "For testing purposes",
                dataObject.getMetadata("purpose"));

            // Check data are available in user metadata map
            assertEquals("Missing creator user metadata",
                "testObjectManagement", dataObject.getUserMetadataMap().get("creator"));
            assertEquals("Missing purpose user metadata",
                "For testing purposes", dataObject.getUserMetadataMap().get("purpose"));
            assertNotNull("Expected data input stream to be available", dataObject.getDataInputStream());

            // Check data are available in service metadata map
            assertNotNull(dataObject.getServiceMetadataMap().get("request-id"));

            // Ensure we can get the data from S3.
            StringBuffer sb = new StringBuffer();
            int b = -1;
            while ((b = dataObject.getDataInputStream().read()) != -1) {
                sb.append((char) b);
            }
            dataObject.closeDataInputStream();
            assertEquals("Mismatching data", objectData, sb.toString());

            // Retrieve only HEAD of data object (all metadata is available, but not the object content
            // data input stream)
            dataObject = service.getObjectDetails(bucketName, object.getKey());
            assertEquals("Unexpected default content type", "text/plain", dataObject.getContentType());
            assertEquals("Mismatching hash", dataMd5HashAsHex, dataObject.getETag());
            assertEquals("Missing creator metadata", "testObjectManagement",
                dataObject.getMetadata("creator"));
            assertEquals("Missing purpose metadata", "For testing purposes",
                dataObject.getMetadata("purpose"));
            assertNull("Expected data input stream to be unavailable", dataObject.getDataInputStream());
            assertEquals("Unexpected size for object", objectData.length(), dataObject.getContentLength());

            // Test object GET constraints.
            Calendar objectCreationTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
            objectCreationTimeCal.setTime(dataObject.getLastModifiedDate());

            Calendar yesterday = (Calendar) objectCreationTimeCal.clone();
            yesterday.add(Calendar.DAY_OF_YEAR, -1);
            Calendar tomorrow = (Calendar) objectCreationTimeCal.clone();
            tomorrow.add(Calendar.DAY_OF_YEAR, +2);

            // Precondition: Modified since yesterday
            service.getObjectDetails(bucketName, object.getKey(), yesterday, null, null, null);
            // Precondition: Mot modified since after creation date.
            try {
                service.getObjectDetails(bucketName, object.getKey(), objectCreationTimeCal, null, null, null);
                fail("Cannot have been modified since object was created");
            } catch (ServiceException e) { }
            // Precondition: Not modified since yesterday
            try {
                service.getObjectDetails(bucketName, object.getKey(), null, yesterday, null, null);
                fail("Cannot be unmodified since yesterday");
            } catch (ServiceException e) { }
            // Precondition: Not modified since tomorrow
            service.getObjectDetails(bucketName, object.getKey(), null, tomorrow, null, null);
            // Precondition: matches correct hash
            service.getObjectDetails(bucketName, object.getKey(), null, null, new String[] {dataMd5HashAsHex}, null);
            // Precondition: doesn't match incorrect hash
            try {
                service.getObjectDetails(bucketName, object.getKey(), null, null,
                    new String[] {"__" + dataMd5HashAsHex.substring(2)}, null);
                fail("Hash values should not match");
            } catch (ServiceException e) {
            }
            // Precondition: doesn't match correct hash
            try {
                service.getObjectDetails(bucketName, object.getKey(), null, null, null, new String[] {dataMd5HashAsHex});
                fail("Hash values should mis-match");
            } catch (ServiceException e) {
            }
            // Precondition: doesn't match incorrect hash
            service.getObjectDetails(bucketName, object.getKey(), null, null, null,
                new String[] {"__" + dataMd5HashAsHex.substring(2)});

            // Retrieve only a limited byte-range of the data, with a start and end.
            Long byteRangeStart = new Long(3);
            Long byteRangeEnd = new Long(12);
            dataObject = service.getObject(bucketName, object.getKey(), null, null, null, null, byteRangeStart, byteRangeEnd);
            String dataReceived = ServiceUtils.readInputStreamToString(
                dataObject.getDataInputStream(), Constants.DEFAULT_ENCODING);
            String dataExpected = objectData.substring(byteRangeStart.intValue(), byteRangeEnd.intValue() + 1);
            assertEquals("Mismatching data from range precondition", dataExpected, dataReceived);

            // Retrieve only a limited byte-range of the data, with a start range only.
            byteRangeStart = new Long(7);
            byteRangeEnd = null;
            dataObject = service.getObject(bucketName, object.getKey(), null, null, null, null, byteRangeStart, byteRangeEnd);
            dataReceived = ServiceUtils.readInputStreamToString(
                dataObject.getDataInputStream(), Constants.DEFAULT_ENCODING);
            dataExpected = objectData.substring(byteRangeStart.intValue());
            assertEquals("Mismatching data from range precondition", dataExpected, dataReceived);

            // Retrieve only a limited byte-range of the data, with an end range only.
            byteRangeStart = null;
            byteRangeEnd = new Long(13);
            dataObject = service.getObject(bucketName, object.getKey(), null, null, null, null, byteRangeStart, byteRangeEnd);
            dataReceived = ServiceUtils.readInputStreamToString(
                dataObject.getDataInputStream(), Constants.DEFAULT_ENCODING);
            dataExpected = objectData.substring(objectData.length() - byteRangeEnd.intValue());
            assertEquals("Mismatching data from range precondition", dataExpected, dataReceived);

            // Clean-up.
            service.deleteObject(bucketName, object.getKey());

            // Create object with tricky key.
            String trickyKey = "http://example.site.com/some/path/document name.html?param1=a@b#c$d&param2=(089)";
            StorageObject trickyObject = service.putObject(bucketName,
                new StorageObject(trickyKey, "Some test data"));
            assertEquals("Tricky key name mistmatch", trickyKey, trickyObject.getKey());

            // Make sure the tricky named object really exists with its full name.
            StorageObject[] objects = service.listObjects(bucketName);
            boolean trickyNamedObjectExists = false;
            for (int i = 0; !trickyNamedObjectExists && i < objects.length; i++) {
                if (trickyKey.equals(objects[i].getKey())) {
                    trickyNamedObjectExists = true;
                }
            }
            assertTrue("Tricky key name object does not exist with its full name", trickyNamedObjectExists);

            // Delete object with tricky key.
            service.deleteObject(bucketName, trickyObject.getKey());

        } finally {
            cleanupBucketForTest("testObjectManagement");
        }
    }
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.