I am using the Java library Metadata-extractor and cannot extract the tag
description correctly using the getUserCommentDescription method code below,
although the tag.getDescription does work:
String exif = "File: " + file;
File jpgFile = new File(file);
Metadata metadata = ImageMetadataReader.readMetadata(jpgFile);
for (Directory directory : metadata.getDirectories()) {
String directoryName = directory.getName();
for (Tag tag : directory.getTags()) {
String tagName = tag.getTagName();
String description = tag.getDescription();
if (tagName.toLowerCase().contains("comment")) {
Log.d("DEBUG", description);
}
exif += "\n " + tagName + ": " + description; //Returns the correct values.
Log.d("DEBUG", directoryName + " " + tagName + " " + description);
}
if (directoryName.equals("Exif IFD0")) {
// create a descriptor
ExifSubIFDDirectory exifDirectory = metadata.getDirectory(ExifSubIFDDirectory.class);
ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(exifDirectory);
Log.d("DEBUG","Comments: " + descriptor.getUserCommentDescription()); //Always null.
}
Am I missing something here?
You are checking for the directory name Exif IFD0 and then accessing the ExifSubIFDDirectory.
Try this code outside the loop:
Metadata metadata = ImageMetadataReader.readMetadata(jpgFile);
ExifSubIFDDirectory exifDirectory = metadata.getDirectory(ExifSubIFDDirectory.class);
ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(exifDirectory);
String comment = descriptor.getUserCommentDescription();
If this returns null then it may be an encoding issue or bug. If you run this code:
byte[] commentBytes =
exifDirectory.getByteArray(ExifSubIFDDirectory.TAG_USER_COMMENT);
Do you have bytes in the array?
If so then please open an issue in the issue tracker and include a sample image that can be used to reproduce the problem. You must authorise any image you provide for use in the public domain.
Related
Trying to generate an SAS Token to access certain files in a Storage Account. I'm using the methods listed here:
https://learn.microsoft.com/en-us/rest/api/eventhub/generate-sas-token
Now, the problem I have is I cannot, for the life of me, make the sasToken string work. If I generate the token via the Portal (Shared Access Signature in the Storage Account), I can access those files via a URL with the provided Token.
However I have yet to be able to generate an SAS token programmatically via Java using the methods I linked above. I think my problem is the StringToSign that is being encrypted. I've been following this example when constructing the string to encrypt:
https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
All my efforts have resulted in either:
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
or
<AuthenticationErrorDetail>Signature did not match. String to sign used was <insert string details here>
Looking at the Portal generated sasToken that works for me:
?sv=2017-11-09&ss=f&srt=o&sp=r&se=2018-12-06T22:15:20Z&st=2018-12-06T14:15:20Z&spr=https&sig=%2Bi1TWv5D80U%2BoaIeoBh1wjaO1p4xVFx4nRZt%2FzwiszY%3D
It seems I need a String like so:
String stringToSign = accountName + "\n" +
"r\n" +
"f\n" +
"o\n" +
URLEncoder.encode(start, "UTF-8") + "\n" +
URLEncoder.encode(expiry, "UTF-8") + "\n" +
"\n" +
"https\n" +
azureApiVersion;
Where accountName is the storage account name from Azure, and start/expiry are the start and expiry strings (ie- 2018-12-06T22:15:20Z) and azureApiVersion is "2017-11-09".
I then try to return the token after constructing the string like so:
String signature = getHMAC256(key, stringToSign);
sasToken = "sv=" + azureApiVersion +
"&ss=f" +
"&srt=o" +
"&sp=r" +
"&se=" +URLEncoder.encode(expiry, "UTF-8") +
"&st=" + URLEncoder.encode(start, "UTF-8") +
"&spr=https" +
"&sig=" + URLEncoder.encode(signature, "UTF-8");
I've tried URL encoding and not URL encoding the the start/expiry dates as well, just in case that was messing things up. What am I missing?
Three points to fix
getHMAC256 method problem as mentioned by #Gaurav
Don't encode expiry and start in stringToSign or the signature won't match. Because the encoded part in url will be decoded by Azure Storage Service to calculate the expected signature.
In stringToSign, miss one \n after azureApiVersion.
Here's the complete sample.
public static void GetFileSAS(){
String accountName = "accountName";
String key = "accountKey";
String resourceUrl = "https://"+accountName+".file.core.windows.net/fileShare/fileName";
String start = "startTime";
String expiry = "expiry";
String azureApiVersion = "2017-11-09";
String stringToSign = accountName + "\n" +
"r\n" +
"f\n" +
"o\n" +
start + "\n" +
expiry + "\n" +
"\n" +
"https\n" +
azureApiVersion+"\n";
String signature = getHMAC256(key, stringToSign);
try{
String sasToken = "sv=" + azureApiVersion +
"&ss=f" +
"&srt=o" +
"&sp=r" +
"&se=" +URLEncoder.encode(expiry, "UTF-8") +
"&st=" + URLEncoder.encode(start, "UTF-8") +
"&spr=https" +
"&sig=" + URLEncoder.encode(signature, "UTF-8");
System.out.println(resourceUrl+"?"+sasToken);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private static String getHMAC256(String accountKey, String signStr) {
String signature = null;
try {
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
sha256HMAC.init(secretKey);
signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}
return signature;
}
I got a simpler method
SharedAccessAccountPolicy sharedAccessAccountPolicy = new SharedAccessAccountPolicy();
sharedAccessAccountPolicy.setPermissionsFromString("racwdlup");
long date = new Date().getTime();
long expiryDate = new Date(date + 8640000).getTime();
sharedAccessAccountPolicy.setSharedAccessStartTime(new Date(date));
sharedAccessAccountPolicy.setSharedAccessExpiryTime(new Date(expiryDate));
sharedAccessAccountPolicy.setResourceTypeFromString("sco");
sharedAccessAccountPolicy.setServiceFromString("bfqt");
String sasToken = "?" + storageAccount.generateSharedAccessSignature(sharedAccessAccountPolicy);
You can get the storage account like this:
private String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=<storage name>;AccountKey=<your key>;EndpointSuffix=core.windows.net";
storageAccount = CloudStorageAccount.parse(storageConnectionString);
<%#page contentType="text/html;charset=euc-kr"%>
<%#page import="com.oreilly.servlet.MultipartRequest" %>
<%#page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%#page import="java.util.*,java.io.*"%>
<%
String saveFolder = "C:/Jsp/myapp/WebContent/ch12/filestorage";
String encType = "euc-kr";
int maxSize = 5 * 1024 * 1024;
try {
MultipartRequest multi = null;
multi = new MultipartRequest(request, saveFolder, maxSize,
encType, new DefaultFileRenamePolicy());
Enumeration params = multi.getParameterNames();
while (params.hasMoreElements()) {
String name = (String) params.nextElement();
String value = multi.getParameter(name);
out.println(name + " = " + value + "<br/>");
}
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
String name = (String) files.nextElement();
String filename = multi.getFilesystemName(name);
String original = multi.getOriginalFileName(name);
String type = multi.getContentType(name);
File f = multi.getFile(name);
out.println("파라미터 이름 : " + name + "<br/>");
out.println("실제 파일 이름 : " + original + "<br/>");
out.println("저장된 파일 이름 : " + filename + "<br/>");
out.println("파일 타입 : " + type + "<br/>");
if (f != null) {
out.println("크기 : " + f.length()+"바이트");
out.println("<br/>");
}
}
} catch (IOException ioe) {
System.out.println(ioe);
} catch (Exception ex) {
System.out.println(ex);
}
%>
this is an example code. the problem is very simple.
eclipse simply cannot find imports even if the external libraries are stored in WebContent/WEB-INF/lib.
I tried reinstallation, searching on the internet and etc for hours
but I still cannot find any solutions for this.
I triple,quadra checked import directive. I cannot see any spelling problem
why does this happen to my eclipse?(I am using eclipse oxygen)
Download cos.jar from: https://jar-download.com/artifact-search/cos
Right click build path
configure build path,
add cos.jar to add external jar
Is there a way to get the name of the class that the script was started from inside the #BeforeSuite annotation when not executed via xml file?
Doing this:
reportName = new Exception().getStackTrace()[0].getClassName();
returns the class itself that contains the #BeforeSuite annotation and this:
reportName = new Exception().getStackTrace()[1].getClassName();
returns sun.reflect.NativeMethodAccessorlmpl
If I execute a script directly from a separate class, I want to get that info because I am using it to name my Extent Report file name.
In case you are wondering what the code inside the #BeforeSuite annotation looks like:
// Set Extent Report file name from the global properties file
String reportName = ctx.getCurrentXmlTest().getSuite().getName();
if (reportName.equals("Default suite"))
{
reportName = new Exception().getStackTrace()[0].getClassName();
}
String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date());
// Initialize Extent Reports and modify the looks/output
String extentReportPath = "";
if (extent == null) {
if (os.equals("Mac"))
{
extentReportPath = reportPath + "/" + project + "-" + reportName + "-" + environment + "-" + browser + "-" + timeStamp + ".html";
}
else if (os.equals("Windows"))
{
extentReportPath = reportPath + "\\" + project + "-" + reportName + "-" + environment + "-" + browser + "-" + timeStamp + ".html";
}
// Start new report
extent = new ExtentReports(extentReportPath, true);
}
There's more to it, but this is the part pertinent to my question.
---UPDATE---
This was my solution:
// Set Extent Report file name from the global properties file
String reportName = ctx.getCurrentXmlTest().getSuite().getName();
if (reportName.equals("Default suite"))
{
List<ITestNGMethod> allMethods = ctx.getSuite().getAllMethods();
for (ITestNGMethod method : allMethods)
{
String fullMethod = method.toString();
int indexOf = fullMethod.indexOf(".");
reportName = fullMethod.replace(fullMethod.substring(indexOf), ""); }
}
You can pass argument ITestContext to the beforesuite method. testNG will auto-inject it. This should have the information you looking for.
context.getSuite().getAllMethods -> List of TestNGMethods.getRealClass() or getTestClass().
I am java developer.I need to get file information from dropbox using java api.
I tried with metadata class.Here i am getting only id,name,path,size of the file.
But i need to get other information like owner name,mimetype,Createddate
ListFolderResult result = client.files().listFolderBuilder("")
.withIncludeDeleted(false)
.withRecursive(true)
.withIncludeMediaInfo(true)
.start();
while (true) {
List<Metadata> entries = result.getEntries();
int idx = 0;
for (Metadata metadata : entries) {
if (metadata instanceof FolderMetadata) {
System.out.println("" + ++idx + ": FOLDER [" + metadata.getPathDisplay() + "], [" + metadata.getName() + "]");
} else if (metadata instanceof FileMetadata) {
System.out.println("" + ++idx + ": File [" + metadata.getPathDisplay() + "], [" + metadata.getName() + "]");
String filePath = metadata.getPathLower().replace(metadata.getName().toLowerCase(), "");
System.out.println(metadata.getPathLower());
System.out.println("FILE PATH"+filePath);
System.out.println("Dropbox"+((FileMetadata) metadata).getRev());
System.out.println("Dropbox"+((FileMetadata) metadata).getClientModified());
System.out.println("Dropbox"+((FileMetadata) metadata).getMediaInfo());
System.out.println("Dropbox"+((FileMetadata) metadata).getMediaInfo().getMetadataValue());
System.out.println("Dropbox"+((FileMetadata) metadata).getSharingInfo());
..
Thanks advance
The FileMetadata object that you get back is documented here:
https://dropbox.github.io/dropbox-sdk-java/api-docs/v2.0.x/com/dropbox/core/v2/files/FileMetadata.html
It doesn't offer the additional information you're looking for, and there isn't another way to get it via the API, but we'll consider this a feature request.
You can keep your own file extension to mime type mapping if you'd like though. For example, you can find our groupings for some file types permission here:
https://www.dropbox.com/developers-v1/reference/devguide
I have a web application that I inherited. I am new to Java so don't beat me up too bad. I have the following method to add new folders to an attachment page. User can create new folders on the page and rename, but how do check to see if a "New Folder" already exists and if so create "New Folder (2)" or "New Folder (3)" etc...
Here is my method from my attachments servlet:
protected void newFolderAction(HttpServletRequest request, HttpServletResponse response, User user, String folderId) throws UnsupportedEncodingException,
IOException {
String key = request.getParameter("key");
String value = request.getParameter("value");
Attachment parent = AttachmentRepository.read(UUID.fromString(key));
String path = parent.getPath();
logger.debug("newFolder: key=" + key + " value=" + value + " path=" + path);
if (AttachmentRepository.read(path + "New Folder/") == null) {
long size = 0L;
boolean isFolder = true;
boolean isPicture = false;
UUID attachmentId = UUID.randomUUID();
Attachment attachment = new Attachment(attachmentId, UUID.fromString(folderId), user.getUnitId(), UUID.fromString("11111111-1111-1111-1111-111111111111"), path + "New Folder/", size, isFolder, isPicture,
"", "0", "0", user.getName(), new Date());
AttachmentRepository.add(attachment);
File directory = new File(Settings.instance().getAttachmentsDir() + "/" + attachment.getPath());
directory.mkdirs();
}
Attachment rootAttachment = AttachmentRepository.read(folderId + "/");
writeJsonAttachmentsTree(response, user, request.getRequestURI(), rootAttachment);
}
There is no custom built-in function in Java that create for you directory if the desired name already exists, You should implement one by Yourself.
public static void main(String[] args) {
File folderPath = new File("c:\\New Folder");
// Check whatever folderPath exists
System.out.println(folderPath.getPath() + " is directory ? " + folderPath.isDirectory());
// Create new folder
File folderCreated = createFolder(folderPath);
System.out.println("The new directory path is: " + folderCreated.getPath());
// Check whatever folderPath exists
System.out.println(folderCreated.getPath() + " is directory ? " + folderCreated.isDirectory());
}
public static File createFolder(File path) {
File pathNum = new File(path.getPath());
String num = "";
int i = 1;
do {
pathNum = new File(path.getPath() + num);
num = "(" + ++i + ")";
} while (!pathNum.mkdir());
return pathNum;
}