How to gracefully check if a raw resource doesn't exist? - java

I have a method in my class called play and I want play which plays an audio file. Which file is played depends on the classes current audioIndex value. Basically, there's a switch like this:
int rId;
switch (audioIndex){
case 0: rId = R.raw.e0.wav; break;
case 1: rId = R.raw.e1.wav; break;
default: rId = R.raw.error.wav; break;
}
After the switch I want to verify if the rId is valid before I pass it to MediaPlayer.create(this, rId). It appears create does not throw an exception if the id doesn't exist or can't be opened. So I must check before passing it?
How to gracefully handle this? Until now I have just assumed the rId will always be correct but I would like to check to make sure.

You can get the resource identifier from the filename with this method. It will return 0 if it is not a valid resource ID. See this question for more.
The project shouldn't compile if the resource doesn't exist though, as R.resourcetype.resourcename won't exist in R.java. This is only useful if you don't know what resources you'll have at runtime.

I would suggest you using my method to get a resource ID. If you make simple exception handling there, you will see, that if your resource does not exist it will be thrown. That would gracefully resolve your issue.
Here's the code:
/**
* #author Lonkly
* #param variableName - name of drawable, e.g R.drawable.<b>image</b>
* #param с - class of resource, e.g R.drawable, of R.raw
* #return integer id of resource
*/
public static int getResId(String variableName, Class<?> с) {
Field field = null;
int resId = 0;
try {
field = с.getField(variableName);
try {
resId = field.getInt(null);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return resId;
}

Related

Java unique code generation failed while calling the recurring function

We have to implement a logic to write the unique code generation in Java. The concept is when we generate the code the system will check if the code is already generate or not. If already generate the system create new code and check again. But this logic fails in some case and we cannot able to identify what is the issue is
Here is the code to create the unique code
Integer code = null;
try {
int max = 999999;
int min = 100000;
code = (int) Math.round(Math.random() * (max - min + 1) + min);
PreOrders preObj = null;
preObj = WebServiceDao.getInstance().preOrderObj(code.toString());
if (preObj != null) {
createCode();
}
} catch (Exception e) {
exceptionCaught();
e.printStackTrace();
log.error("Exception in method createCode() - " + e.toString());
}
return code;
}
The function preOrderObj is calling a function to check the code exists in the database if exists return the object. We are using Hibernate to map the database functions and Mysql on the backend.
Here is the function preOrderObj
PreOrders preOrderObj = null;
List<PreOrders> preOrderList = null;
SessionFactory sessionFactory =
(SessionFactory) ServletActionContext.getServletContext().getAttribute(HibernateListener.KEY_NAME);
Session Hibernatesession = sessionFactory.openSession();
try {
Hibernatesession.beginTransaction();
preOrderList = Hibernatesession.createCriteria(PreOrders.class).add(Restrictions.eq("code", code)).list(); // removed .add(Restrictions.eq("status", true))
if (!preOrderList.isEmpty()) {
preOrderObj = (PreOrders) preOrderList.iterator().next();
}
Hibernatesession.getTransaction().commit();
Hibernatesession.flush();
} catch (Exception e) {
Hibernatesession.getTransaction().rollback();
log.debug("This is my debug message.");
log.info("This is my info message.");
log.warn("This is my warn message.");
log.error("This is my error message.");
log.fatal("Fatal error " + e.getStackTrace().toString());
} finally {
Hibernatesession.close();
}
return preOrderObj;
}
Please guide us to identify the issue.
In createCode method, when the random code generated already exist in database, you try to call createCode again. However, the return value from the recursive call is not updated to the code variable, hence the colliding code is still returned and cause error.
To fix the problem, update the method as
...
if (preObj != null) {
//createCode();
code = createCode();
}
...
Such that the code is updated.
By the way, using random number to generate unique value and test uniqueness through query is a bit strange. You may try Auto Increment if you want unique value.

Access Permission not working

I have been trying to put permission on my pdf.
I have a method which will set the Access Permission on an instance variable called access
private AccessPermission access = new AccessPermission();
public void setPdfPermissions(boolean allowPrint, boolean degradePrint,
boolean editPage, boolean allowAssembly, boolean allowCopy,
boolean allowReaders, boolean editAnnotation, boolean allowFillIn) {
if (allowPrint) { // allow printing
access.setCanPrint(allowPrint);
}
if (degradePrint) { // degrade printing
access.setCanPrintDegraded(allowAssembly);
}
if (editPage) { // edit page contents
access.setCanModify(editPage);
}
if (allowAssembly) { // insert, remote or rotate page
access.setCanAssembleDocument(allowAssembly);
}
if (allowCopy) { // copy page contents or graphics
access.setCanExtractForAccessibility(allowCopy);
}
if (allowReaders) { // screen readers can copy contents or graphics
access.setReadOnly();
}
if (editAnnotation) { // edit annotations
access.setCanModifyAnnotations(editAnnotation);
}
if (allowFillIn) { // fill form fields
access.setCanFillInForm(allowFillIn);
}
}
and then I m saving the access in security handler
StandardSecurityHandler secHandler = new StandardSecurityHandler();
if((userPass != null) || (ownerPass != null)) {
System.out.println("userPass:"+userPass+"owner pass:"+userPass);
// TODO
StandardProtectionPolicy policy = new StandardProtectionPolicy(ownerPass.toString(), userPass.toString(),
access);
secHandler = new StandardSecurityHandler(policy);
document.setSecHandler(secHandler);
When Im passing false for values like setPrint as false, Its allowing me to print. Any help is highly appreciated.
In addition to #Tilman's answer, the first code block also is wrong:
For each boolean parameter, setPdfPermissions only does something if the value is true, e.g.:
if (allowPrint) { // allow printing
access.setCanPrint(allowPrint);
}
This would work if the permission by default was not granted. Looking at the definition of the AccessPermission default constructor, though, one sees that the contrary is the case, e.g. in the code from 1.8.10:
/**
* Create a new access permission object.
* By default, all permissions are granted.
*/
public AccessPermission()
{
bytes = DEFAULT_PERMISSIONS;
}
Thus, setPdfPermissions essentialis is a big NOP (no-operation) block of code.
Your second code block is wrong. The correct way (at least for the 1.8 versions) to encrypt a file is described here. So for you, the correct code would be:
// owner password to open the file with all permissions
// user password to open the file but with restricted permissions, can be empty
StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPass, userPass, access);
spp.setEncryptionKeyLength(128);
doc.protect(spp);
edit: see also the answer by mkl why your 1st code segment is wrong too :-)

PMD rules: How to properly solve this DD-anomaly issue

I have the following Android code:
public final List<MyObj> getList() {
Cursor cursor = null;
try {
final String queryStr = GET_LIST_STATEMENT;
cursor = db.rawQuery(queryStr, new String[] {});
List<MyObj> list = null;
//here I get the data from de cursor.
return list ;
} catch (SQLiteFullException ex) {
//do something to treat the exception.
} finally {
if (cursor != null) {
cursor.close();
}
}
}
When I run PMD analysis over this code, I get the following issue: Found 'DD'-anomaly for variable 'cursor' (lines '182'-'185').
The line 182 is: Cursor cursor = null;.
The line 185 is: cursor = db.rawQuery(queryStr, new String[] {});
So, I understand that the problem is that I'm doing a Premature Initialization in the line 182 (I never read the variable between the lines 182 and 185), but if I don't do that, I can't have the code closing the cursor in the finally block.
What to do in this case? Just ignore this PMD issue? Can I configure PMD to don't rise up this specific kind of DD-anomaly (not all DD-anomaly)? Should PMD be smart enough to doesn't rise up this issue?
Another example of DD-anomaly that I think is not a real problem:
Date distributeDate;
try {
distributeDate = mDf.parse(someStringDate);
} catch (ParseException e) {
Log.e("Problem", "Problem parsing the date of the education. Apply default date.");
distributeDate = Calendar.getInstance().getTime();
}
In this case, the anomaly occurs with the distributeDate variable.
The documentation is pretty easy to understand:
Either you use annotations to suppress warnings:
// This will suppress UnusedLocalVariable warnings in this class
#SuppressWarnings("PMD.UnusedLocalVariable")
public class Bar {
void bar() {
int foo;
}
}
or you use a comment:
public class Bar {
// 'bar' is accessed by a native method, so we want to suppress warnings for it
private int bar; //NOPMD
}
When it comes to your specific code, I'd say that the easiest way to handle it is to not use a finally block even though this would look like the perfect place for it.

How do I get the name of a referenced Project or Library?

I am currently developing a plugin for Eclipse that analyzes dependencies and references of Java and plugin projects in the Workspace.
However I cannot for the life of me find a way to get the name of a referenced project or library found in the Classpath Entries.
Here's what I have (excerpt from a longer method):
IJavaProject j= JavaCore.create(project); //project is an IProject
try {
IClasspathEntry[] classpath= j.getRawClasspath();
// Get required Libraries and Projects
for (IClasspathEntry entry : classpath) {
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY: {
//Retrieve name of the Library
break;
}
case IClasspathEntry.CPE_PROJECT: {
//Retrieve name of the Project
break;
}
}
} catch [...]
Does anyone have an idea how to get the names at the marked positions, or a better way to retrieve them?
After consulting with someone else, I have finally found the solution:
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY: {
String name = entry.getPath().segment(0);
/* Further processing for a Library
*...
*/
break;
}
case IClasspathEntry.CPE_PROJECT: {
String name = entry.getPath().segment(0);
/* Further processing for a Project
*...
*/
break;
}

LDAP Not processing showing SchemaViolationException

I am having a LDAP Queue which process a object class.I cant find the exact location why it is giving the exception. The objclass is a concadenation string with pipe symbol. Any program coding to find the exact location in which concadination part is going to the Exception?.Please Assist.
try {
Attributes objClass = null;
try {
objClass = getObjClass(LdapInfo.PER_ID, person.perId);
} catch (NamingException e)
{
DCXError.myInstance().writeError("LdapUpdaterConnection: " + e.getMessage());
}
NamingEnumeration oc = objClass.get("objectclass").getAll();
String baseObjClass = null;
while (oc.hasMoreElements()) {
baseObjClass = (String) oc.nextElement();
if (baseObjClass.equalsIgnoreCase(LdapInfo.NON_EMPLOYEE_PERSON)
|| baseObjClass.equalsIgnoreCase("N/A")||
baseObjClass.equalsIgnoreCase(LdapInfo.EMPLOYEE_PERSON))
break;
}
} catch (SchemaViolationException e4) {
DCXError.myInstance().writeError(
"LdapUpdaterConnection:doUpdate SchemaViolationException "+ e4.getExplanation());
DCXError.myInstance().writeError("LdapUpdaterConnection:update persID = " + personId);
return (LdapUpdaterConnection.BAD_DATA);
}
You can't find the exact location only because you haven't logged the stack trace. You would also need to reformat your code so that each statement is on a separate line to make any use of that information. You should also use variable names that actually correspond to the content.
This is really terrible code.
It's also hard to see why you are doing all this in the first place. A decent query filter would do all that for you far more simply.

Categories