Obtain informations on supported media formats programmatically? - java

How can I obtain information about device supported media formats?
I'm targeting everything from API 15 and up and I would like to know for example which profile of "h264/avc" device supports.

See these classes:
MimeTypeMap.java (frameworks\base\core\java\android
\webkit)
Here is ContentType.java (frameworks\base\core\java\com\google\android\mms) provides all format supported by android device.
package com.google.android.mms;
import java.util.ArrayList;
public class ContentType {
public static final String MMS_MESSAGE = "application/vnd.wap.mms-message";
// The phony content type for generic PDUs (e.g. ReadOrig.ind,
// Notification.ind, Delivery.ind).
public static final String MMS_GENERIC = "application/vnd.wap.mms-generic";
public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed";
public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related";
public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative";
public static final String TEXT_PLAIN = "text/plain";
public static final String TEXT_HTML = "text/html";
public static final String TEXT_VCALENDAR = "text/x-vCalendar";
public static final String TEXT_VCARD = "text/x-vCard";
public static final String IMAGE_UNSPECIFIED = "image/*";
public static final String IMAGE_JPEG = "image/jpeg";
public static final String IMAGE_JPG = "image/jpg";
public static final String IMAGE_GIF = "image/gif";
public static final String IMAGE_WBMP = "image/vnd.wap.wbmp";
public static final String IMAGE_PNG = "image/png";
public static final String AUDIO_UNSPECIFIED = "audio/*";
public static final String AUDIO_AAC = "audio/aac";
public static final String AUDIO_AMR = "audio/amr";
public static final String AUDIO_IMELODY = "audio/imelody";
public static final String AUDIO_MID = "audio/mid";
public static final String AUDIO_MIDI = "audio/midi";
public static final String AUDIO_MP3 = "audio/mp3";
public static final String AUDIO_MPEG3 = "audio/mpeg3";
public static final String AUDIO_MPEG = "audio/mpeg";
public static final String AUDIO_MPG = "audio/mpg";
public static final String AUDIO_MP4 = "audio/mp4";
public static final String AUDIO_X_MID = "audio/x-mid";
public static final String AUDIO_X_MIDI = "audio/x-midi";
public static final String AUDIO_X_MP3 = "audio/x-mp3";
public static final String AUDIO_X_MPEG3 = "audio/x-mpeg3";
public static final String AUDIO_X_MPEG = "audio/x-mpeg";
public static final String AUDIO_X_MPG = "audio/x-mpg";
public static final String AUDIO_3GPP = "audio/3gpp";
public static final String AUDIO_OGG = "application/ogg";
public static final String VIDEO_UNSPECIFIED = "video/*";
public static final String VIDEO_3GPP = "video/3gpp";
public static final String VIDEO_3G2 = "video/3gpp2";
public static final String VIDEO_H263 = "video/h263";
public static final String VIDEO_MP4 = "video/mp4";
public static final String APP_SMIL = "application/smil";
public static final String APP_WAP_XHTML = "application/vnd.wap.xhtml+xml";
public static final String APP_XHTML = "application/xhtml+xml";
public static final String APP_DRM_CONTENT = "application/vnd.oma.drm.content";
public static final String APP_DRM_MESSAGE = "application/vnd.oma.drm.message";
private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>();
private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>();
private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>();
private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>();
static {
sSupportedContentTypes.add(TEXT_PLAIN);
sSupportedContentTypes.add(TEXT_HTML);
sSupportedContentTypes.add(TEXT_VCALENDAR);
sSupportedContentTypes.add(TEXT_VCARD);
sSupportedContentTypes.add(IMAGE_JPEG);
sSupportedContentTypes.add(IMAGE_GIF);
sSupportedContentTypes.add(IMAGE_WBMP);
sSupportedContentTypes.add(IMAGE_PNG);
sSupportedContentTypes.add(IMAGE_JPG);
//supportedContentTypes.add(IMAGE_SVG); not yet supported.
sSupportedContentTypes.add(AUDIO_AAC);
sSupportedContentTypes.add(AUDIO_AMR);
sSupportedContentTypes.add(AUDIO_IMELODY);
sSupportedContentTypes.add(AUDIO_MID);
sSupportedContentTypes.add(AUDIO_MIDI);
sSupportedContentTypes.add(AUDIO_MP3);
sSupportedContentTypes.add(AUDIO_MPEG3);
sSupportedContentTypes.add(AUDIO_MPEG);
sSupportedContentTypes.add(AUDIO_MPG);
sSupportedContentTypes.add(AUDIO_X_MID);
sSupportedContentTypes.add(AUDIO_X_MIDI);
sSupportedContentTypes.add(AUDIO_X_MP3);
sSupportedContentTypes.add(AUDIO_X_MPEG3);
sSupportedContentTypes.add(AUDIO_X_MPEG);
sSupportedContentTypes.add(AUDIO_X_MPG);
sSupportedContentTypes.add(AUDIO_3GPP);
sSupportedContentTypes.add(AUDIO_OGG);
sSupportedContentTypes.add(VIDEO_3GPP);
sSupportedContentTypes.add(VIDEO_3G2);
sSupportedContentTypes.add(VIDEO_H263);
sSupportedContentTypes.add(VIDEO_MP4);
sSupportedContentTypes.add(APP_SMIL);
sSupportedContentTypes.add(APP_WAP_XHTML);
sSupportedContentTypes.add(APP_XHTML);
sSupportedContentTypes.add(APP_DRM_CONTENT);
sSupportedContentTypes.add(APP_DRM_MESSAGE);
// add supported image types
sSupportedImageTypes.add(IMAGE_JPEG);
sSupportedImageTypes.add(IMAGE_GIF);
sSupportedImageTypes.add(IMAGE_WBMP);
sSupportedImageTypes.add(IMAGE_PNG);
sSupportedImageTypes.add(IMAGE_JPG);
// add supported audio types
sSupportedAudioTypes.add(AUDIO_AAC);
sSupportedAudioTypes.add(AUDIO_AMR);
sSupportedAudioTypes.add(AUDIO_IMELODY);
sSupportedAudioTypes.add(AUDIO_MID);
sSupportedAudioTypes.add(AUDIO_MIDI);
sSupportedAudioTypes.add(AUDIO_MP3);
sSupportedAudioTypes.add(AUDIO_MPEG3);
sSupportedAudioTypes.add(AUDIO_MPEG);
sSupportedAudioTypes.add(AUDIO_MPG);
sSupportedAudioTypes.add(AUDIO_MP4);
sSupportedAudioTypes.add(AUDIO_X_MID);
sSupportedAudioTypes.add(AUDIO_X_MIDI);
sSupportedAudioTypes.add(AUDIO_X_MP3);
sSupportedAudioTypes.add(AUDIO_X_MPEG3);
sSupportedAudioTypes.add(AUDIO_X_MPEG);
sSupportedAudioTypes.add(AUDIO_X_MPG);
sSupportedAudioTypes.add(AUDIO_3GPP);
sSupportedAudioTypes.add(AUDIO_OGG);
// add supported video types
sSupportedVideoTypes.add(VIDEO_3GPP);
sSupportedVideoTypes.add(VIDEO_3G2);
sSupportedVideoTypes.add(VIDEO_H263);
sSupportedVideoTypes.add(VIDEO_MP4);
}
// This class should never be instantiated.
private ContentType() {
}
public static boolean isSupportedType(String contentType) {
return (null != contentType) && sSupportedContentTypes.contains(contentType);
}
public static boolean isSupportedImageType(String contentType) {
return isImageType(contentType) && isSupportedType(contentType);
}
public static boolean isSupportedAudioType(String contentType) {
return isAudioType(contentType) && isSupportedType(contentType);
}
public static boolean isSupportedVideoType(String contentType) {
return isVideoType(contentType) && isSupportedType(contentType);
}
public static boolean isTextType(String contentType) {
return (null != contentType) && contentType.startsWith("text/");
}
public static boolean isImageType(String contentType) {
return (null != contentType) && contentType.startsWith("image/");
}
public static boolean isAudioType(String contentType) {
return (null != contentType) && contentType.startsWith("audio/");
}
public static boolean isVideoType(String contentType) {
return (null != contentType) && contentType.startsWith("video/");
}
public static boolean isDrmType(String contentType) {
return (null != contentType)
&& (contentType.equals(APP_DRM_CONTENT)
|| contentType.equals(APP_DRM_MESSAGE));
}
public static boolean isUnspecified(String contentType) {
return (null != contentType) && contentType.endsWith("*");
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getImageTypes() {
return (ArrayList<String>) sSupportedImageTypes.clone();
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getAudioTypes() {
return (ArrayList<String>) sSupportedAudioTypes.clone();
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getVideoTypes() {
return (ArrayList<String>) sSupportedVideoTypes.clone();
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getSupportedTypes() {
return (ArrayList<String>) sSupportedContentTypes.clone();
}
}
check related details here - http://developer.android.com/reference/android/media/package-summary.html
Hope this helps you.

Related

What is the faster way to add the items from a class to an ArrayList to create a ListView?

public class LengthConversion {
public static final String M_TO_CM = "meter to centimeter";
public static final String M_TO_MM = "meter to millimeter";
public static final String M_TO_DM = "meter to decimeter";
public static final String KM_TO_M = "kilometer to meter";
public static final String INCH_TO_M = "inch to meter";
public static final String FOOT_TO_M = "foot to meter";
public static final String ASM_TO_M = "angstrom to meter";
public static final String FM_TO_M = "fermi to meter";
public static final String MILE_TO_KM = "mile to kilometer";}
I am adding these string to the ArrayList one by one by .add() function. Is there another way?
Maybe you need an enum:
public enum LengthConversion {
M_TO_CM("meter to centimeter"),
M_TO_MM("meter to millimeter"),
M_TO_DM("meter to decimeter"),
KM_TO_M("kilometer to meter"),
INCH_TO_M("inch to meter"),
FOOT_TO_M("foot to meter"),
ASM_TO_M("angstrom to meter"),
FM_TO_M("fermi to meter"),
MILE_TO_KM("mile to kilometer");
public final String conversion;
LengthConversion(String conversion) {
this.conversion = conversion;
}
}

How do I set limited generic return type

Taking the following 2 objects, I cant figure out how to make the following work.
public final *Generic SubType* getInfo(){
...
}
First the class I am working with
public class ResultEntry<Type extends ResultType>{
private final Type mType;
private final String mLabel;
private final String mInfo;
private ResultEntry(final Type t, final String label, final String info){
mType = t;
mLabel = label;
mInfo = info;
}
public static ResultEntry<ResultType> newInstance(final String label, final Number info){
return new ResultEntry<>(ResultType.NUMBER, label, info.toString());
}
public static ResultEntry<ResultType> newInstance(final String label, final Boolean info){
return new ResultEntry<>(ResultType.NUMBER, label, info.toString());
}
public static ResultEntry<ResultType> newInstance(final String label, final String info){
return new ResultEntry<>(ResultType.NUMBER, label, info);
}
public final ResultType getType(){
return mType;
}
public final String getLabel(){
return mLabel;
}
public final *Generic SybType* getInfo(){
}
}
And then enum ResultType
public enum ResultType {
STRING ("STRING"),
BOOLEAN ("BOOLEAN"),
NUMBER ("NUMBER");
private final String s;
ResultType(final String string){
s = string;
}
public final boolean isString(){
return s.equals(STRING.s);
}
public final boolean isBoolean(){
return s.equals(BOOLEAN.s);
}
public final boolean isNumber(){
return s.equals(NUMBER.s);
}
}
What I would like to do is have a way to check what mType is (String, Boolean, or Number) and then return that actual object. Something like,
public final *Generic SubType* getInfo(){
if(mType.isString()) return new String();
if(mType.isNumber()) return new Number();
if(mType.isBoolean()) return new Boolean();
}
Though obviously I would have actual information to pass back instead.
But I dont know if that is possible, and if so, I don't know how I would go about doing it. It does appear that Android is able to do it via AsyncTask.
For reference, I found most of this from This Question
I would suggest you do it like this, which doesn't convert the info values to String, i.e. mInfo is Object, not String.
public class ResultEntry<R> {
private final ResultType mType;
private final String mLabel;
private final Object mInfo;
private ResultEntry(final ResultType t, final String label, final Object info) {
this.mType = t;
this.mLabel = label;
this.mInfo = info;
}
public static ResultEntry<Number> newInstance(final String label, final Number info) {
return new ResultEntry<>(ResultType.NUMBER, label, info);
}
public static ResultEntry<Boolean> newInstance(final String label, final Boolean info) {
return new ResultEntry<>(ResultType.BOOLEAN, label, info);
}
public static ResultEntry<String> newInstance(final String label, final String info) {
return new ResultEntry<>(ResultType.STRING, label, info);
}
public final ResultType getType() {
return this.mType;
}
public final String getLabel() {
return this.mLabel;
}
#SuppressWarnings("unchecked")
public final R getInfo() {
return (R) this.mInfo;
}
}
Then you use it like this:
ResultEntry<Number> numEntry = ResultEntry.newInstance("", 5);
ResultEntry<Boolean> boolEntry = ResultEntry.newInstance("", true);
ResultEntry<String> strEntry = ResultEntry.newInstance("", "Foo");
Number numInfo = numEntry.getInfo();
Boolean boolInfo = boolEntry.getInfo();
String strInfo = strEntry.getInfo();

Append a string to a static final String declared in an abstract class

I have the following abstract class
public abstract class IStreamSorterTest<T> {
protected static String FOLDER_NAME = null;
protected static String FILE_EXT = null;
protected static String SCHEMA_FILE_EXT = null;
protected static final String PATH_PREFIX = "src/test/resources/" + FOLDER_NAME;
protected static final String USERS_FILE = "users" + FILE_EXT;
protected static final String SORTED_USERS_FILE = "sorted_users" + FILE_EXT;
protected static final String USERS_XML_SCHEMA = "users_schema" + SCHEMA_FILE_EXT;
Extended by several classes in which I would like to ONLY define the variables FOLDER_NAME, FILE_EXT and SCHEMA_FILE_EXT without creating new variables.
What is the best way to do it?
You can't make these variables static as they would only exist in the superclass.
You could pass these Strings to the abstract class' constructor:
public abstract class IStreamSorterTest<T> {
protected final String pathPrefix;
protected final String userFile;
protected final String sortedUserFile;
protected final String usersXMLSchema;
protected IStreamSorterTest(String folderName, String fileExt, String schemaFileExt) {
pathPrefix = "src/test/resources/" + folderName;
userFile = "users" + fileExt;
sortedUserFile = "sorted_users" + fileExt;
usersXMLSchema = "users_schema" + schemaFileExt;
}
}
Then in a subclass:
public class SomeClass extends IStreamSorterTest<SomeType> {
private static final String FOLDER_NAME = ...;
private static final String FILE_EXT = ...;
private static final String SCHEMA_FILE_EXT = ...;
public SomeClass() {
super(FOLDER_NAME, FILE_EXT, SCHEMA_FILE_EXT);
}
}

Access to a Bean property from a Java JSP View is not working

I have an object with these attributes:
public final class CaseNote {
private final Long caseNoteId;
private final Long subGroupId;
private final String title;
private final String caseNoteTypeCode;
private final Date contactDate;
private final Date completedDateTime;
private final Long personVisitId;
private final Date createdDateTime;
private final Long createdByWorkerId;
private final Long createdByTeamId;
private final List<CaseNoteDetailsDTO> noteDetails = new ArrayList<CaseNoteDetailsDTO>();
private final List<GroupMemberDetailsDTO> selectedMembers = new ArrayList<GroupMemberDetailsDTO>();
private final ReferenceProvider referenceProvider;
private final Date timeOutDate;
public CaseNote(final CaseNotesDTO caseNoteDto, final List<CaseNoteDetailsDTO> noteDetails,
final List<GroupMemberDetailsDTO> selectedMembers, final ReferenceProvider referenceProvider) {
this.caseNoteId = caseNoteDto.getCaseNoteId();
this.subGroupId = caseNoteDto.getSubGroupId();
this.title = caseNoteDto.getTitle();
this.caseNoteTypeCode = caseNoteDto.getCaseNoteTypeCode();
this.contactDate = caseNoteDto.getContactDateTime();
this.completedDateTime = caseNoteDto.getCompletedDateTime();
this.personVisitId = caseNoteDto.getPersonVisitId();
this.createdDateTime = caseNoteDto.getCreatedDateTime();
this.createdByWorkerId = caseNoteDto.getCreatedByWorkerId();
this.createdByTeamId = caseNoteDto.getCreatedByTeamId();
this.timeOutDate = caseNoteDto.getTimeOutDate();
this.noteDetails.clear();
this.selectedMembers.clear();
this.noteDetails.addAll(noteDetails);
Collections.sort(this.noteDetails, new CaseNoteDetailCreatedDateComparator());
this.selectedMembers.addAll(selectedMembers);
this.referenceProvider = referenceProvider;
}
private class CaseNoteDetailCreatedDateComparator implements Comparator<CaseNoteDetailsDTO> {
#Override
public int compare(final CaseNoteDetailsDTO firstCaseNoteDetail, final CaseNoteDetailsDTO secondCaseNoteDetail) {
return firstCaseNoteDetail.getCreatedDateTime().compareTo(secondCaseNoteDetail.getCreatedDateTime());
}
}
public Long getCaseNoteId() {
return caseNoteId;
}
public Long getSubGroupId() {
return subGroupId;
}
public String getTitle() {
return title;
}
public String getCaseNoteTypeCode() {
return caseNoteTypeCode;
}
public Date getContactDate() {
return contactDate;
}
public Date getCompletedDateTime() {
return completedDateTime;
}
public Long getPersonVisitId() {
return personVisitId;
}
public Date getCreatedDateTime() {
return createdDateTime;
}
public Long getCreatedByWorkerId() {
return createdByWorkerId;
}
public Long getCreatedByTeamId() {
return createdByTeamId;
}
public List<CaseNoteDetailsDTO> getNoteDetails() {
return Collections.unmodifiableList(noteDetails);
}
public List<GroupMemberDetailsDTO> getSelectedMembers() {
return Collections.unmodifiableList(selectedMembers);
}
public boolean isSignificant() {
boolean significantEvent = false;
for (final CaseNoteDetailsDTO detail : this.getNoteDetails()) {
significantEvent = significantEvent || detail.isSignificantEvent();
}
return significantEvent;
}
public String getCaseNoteTypeDescription() {
return referenceProvider.provide(ReferenceDomain.CASENOTE_TYPE, getCaseNoteTypeCode());
}
public CaseNoteDetailsDTO getRootNoteDetails() {
validateCaseNoteDetailsExists();
return getNoteDetails().get(0);
}
public List<CaseNoteDetailsDTO> getAppendments() {
validateCaseNoteDetailsExists();
return getNoteDetails().subList(1, getNoteDetails().size());
}
private void validateCaseNoteDetailsExists() {
if (getNoteDetails() == null || getNoteDetails().isEmpty()) {
throw new IllegalStateException("No case note details found");
}
}
public List<String> getMemberNames() {
final List<String> memberNames = new ArrayList<String>();
final List<GroupMemberDetailsDTO> selectedMembers = getSelectedMembers();
for (final GroupMemberDetailsDTO memberDetails : selectedMembers) {
memberNames.add(memberDetails.getName());
}
return memberNames;
}
public Date getTimeOutDate() {
return timeOutDate;
}
public boolean isTimedOut() {
return completedDateTime == null && new Date().after(this.timeOutDate);
}
}
From a JSP file, I would like to print the attribute 'createdWorkerId', but it's not working. I tried to print the title and it works, but not with the createdWorkerId. The line is the following:
<span class="highlighted"><%=noteClassDescription%>: <c:out value="${casenote.createdByWorkerId}"/> </span>
Should I parse the createdWorkerId to a String before or the problem is other? Any help appreciated.
Thanks.

Pretty printing a method in ASM Bytecode

I am trying (with no success) to print only the contents of a given method. The following code almost does the trick:
class MyTraceMethodVisitor extends MethodVisitor {
public MyTraceMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM4, mv);
}
#Override
public void visitMaxs(int maxStack, int maxLocals) {
}
}
class MyClassVisitor extends ClassVisitor {
public MyClassVisitor(ClassVisitor cv) {
super(Opcodes.ASM4, cv);
}
#Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
return null;
}
#Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
if (name.equals("get777"))
return new MyTraceMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
return null;
}
}
running it with
ClassReader classReader = new ClassReader("something.Point");
PrintWriter printWriter = new PrintWriter(System.out);
TraceClassVisitor traceClassVisitor = new TraceClassVisitor(printWriter);
MyClassVisitor myClassVisitor = new MyClassVisitor(traceClassVisitor);
classReader.accept(myClassVisitor, ClassReader.SKIP_DEBUG);
resulting in
// class version 50.0 (50)
// access flags 0x21
public class something/Point {
// access flags 0x1
public get777()I
SIPUSH 777
IRETURN
}
What I'd like to get was just
SIPUSH 777
IRETURN
without signature, comments and whatsoever.
How can I accomplish that?
The answer is already pretty old and involves writing much code.
As of asm v5 printing method instructions is straightforward:
// Setup for asm ClassReader, ClassWriter and your implementation of the ClassVisitor(e.g.: YourClassVisitor)
final ClassReader reader = new ClassReader(classBytes);
final ClassWriter writer = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
final ClassVisitor visitor =new YourClassVisitor(Opcodes.ASM5, visitor);
In your implementation of the ClassVisitor, simply override the visitMethod method. Here an example:
public class YourClassVisitor extends ClassVisitor {
public InstrumentationClassVisitor(int api, ClassVisitor cv) {
super(api, cv);
}
#Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
Printer p = new Textifier(Opcodes.ASM5) {
#Override
public void visitMethodEnd() {
print(new PrintWriter(System.out)); // print it after it has been visited
}
};
return new TraceMethodVisitor(mv, p);
}
}
The TraceMethodVisitor will receive the event calls for visiting method instructions etc. by the classVisitor. The code will then be printed by the TraceMethodVisitor with the help of the Printer.
This seems to do the trick.. although I don't understand how:
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;
public class BytecodePrettyPrinter {
/**
* Gets us the bytecode method body of a given method.
* #param className The class name to search for.
* #param methodName The method name.
* #param methodDescriptor The method's descriptor.
* Can be null if one wishes to just get the first
* method with the given name.
* #throws IOException
*/
public static String[] getMethod(String className, String methodName, String methodDescriptor) throws IOException {
ClassReader classReader = new ClassReader(className);
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
TraceClassVisitor traceClassVisitor = new TraceClassVisitor(null, new SourceCodeTextifier(), printWriter);
MethodSelectorVisitor methodSelectorVisitor = new MethodSelectorVisitor(traceClassVisitor, methodName, methodDescriptor);
classReader.accept(methodSelectorVisitor, ClassReader.SKIP_DEBUG);
return toList(stringWriter.toString());
}
/**
* Gets us the bytecode method body of a given method.
* #param className The class name to search for.
* #param methodName The method name.
* #throws IOException
*/
public static String[] getMethod(String className, String methodName) throws IOException {
return getMethod(className, methodName, null);
}
private static String[] toList(String str) {
//won't work correctly for all OSs
String[] operations = str.split("[" + "\n" + "]");
for (int i = 0; i < operations.length; ++i) {
operations[i] = operations[i].trim();
}
return operations;
}
private static class MethodSelectorVisitor extends ClassVisitor {
private final String methodName;
private final String methodDescriptor;
public MethodSelectorVisitor(ClassVisitor cv, String methodName, String methodDescriptor) {
super(Opcodes.ASM4, cv);
this.methodName = methodName;
this.methodDescriptor = methodDescriptor;
}
#Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
if (methodName.equals(name)) {
if (methodDescriptor == null)
return new MaxVisitFilterMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
if (methodDescriptor.equals(desc))
return new MaxVisitFilterMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
}
return null;
}
}
private static class MaxVisitFilterMethodVisitor extends MethodVisitor {
public MaxVisitFilterMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM4, mv);
}
#Override
public void visitMaxs(int maxStack, int maxLocals) {
}
}
private static class SourceCodeTextifier extends Printer {
public SourceCodeTextifier() {
this(Opcodes.ASM4);
}
protected SourceCodeTextifier(final int api) {
super(api);
}
#Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces)
{
}
#Override
public void visitSource(final String file, final String debug) {
}
#Override
public void visitOuterClass(
final String owner,
final String name,
final String desc)
{
}
#Override
public Textifier visitClassAnnotation(
final String desc,
final boolean visible)
{
return new Textifier();
}
#Override
public void visitClassAttribute(final Attribute attr) {
}
#Override
public void visitInnerClass(
final String name,
final String outerName,
final String innerName,
final int access)
{
}
#Override
public Textifier visitField(
final int access,
final String name,
final String desc,
final String signature,
final Object value)
{
return new Textifier();
}
#Override
public Textifier visitMethod(
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions)
{
Textifier t = new Textifier();
text.add(t.getText());
return t;
}
#Override
public void visitClassEnd() {
}
#Override
public void visit(final String name, final Object value) {
}
#Override
public void visitEnum(
final String name,
final String desc,
final String value)
{
}
#Override
public Textifier visitAnnotation(
final String name,
final String desc)
{
return new Textifier();
}
#Override
public Textifier visitArray(
final String name)
{
return new Textifier();
}
#Override
public void visitAnnotationEnd() {
}
#Override
public Textifier visitFieldAnnotation(
final String desc,
final boolean visible)
{
return new Textifier();
}
#Override
public void visitFieldAttribute(final Attribute attr) {
visitAttribute(attr);
}
#Override
public void visitFieldEnd() {
}
#Override
public Textifier visitAnnotationDefault() {
return new Textifier();
}
#Override
public Textifier visitMethodAnnotation(
final String desc,
final boolean visible)
{
return new Textifier();
}
#Override
public Textifier visitParameterAnnotation(
final int parameter,
final String desc,
final boolean visible)
{
return new Textifier();
}
#Override
public void visitMethodAttribute(final Attribute attr) {
}
#Override
public void visitCode() {
}
#Override
public void visitFrame(
final int type,
final int nLocal,
final Object[] local,
final int nStack,
final Object[] stack)
{
}
#Override
public void visitInsn(final int opcode) {
}
#Override
public void visitIntInsn(final int opcode, final int operand) {
}
#Override
public void visitVarInsn(final int opcode, final int var) {
}
#Override
public void visitTypeInsn(final int opcode, final String type) {
}
#Override
public void visitFieldInsn(
final int opcode,
final String owner,
final String name,
final String desc)
{
}
#Override
public void visitMethodInsn(
final int opcode,
final String owner,
final String name,
final String desc)
{
}
#Override
public void visitInvokeDynamicInsn(
String name,
String desc,
Handle bsm,
Object... bsmArgs)
{
}
#Override
public void visitJumpInsn(final int opcode, final Label label) {
}
#Override
public void visitLabel(final Label label) {
}
#Override
public void visitLdcInsn(final Object cst) {
}
#Override
public void visitIincInsn(final int var, final int increment) {
}
#Override
public void visitTableSwitchInsn(
final int min,
final int max,
final Label dflt,
final Label... labels)
{
}
#Override
public void visitLookupSwitchInsn(
final Label dflt,
final int[] keys,
final Label[] labels)
{
}
#Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
}
#Override
public void visitTryCatchBlock(
final Label start,
final Label end,
final Label handler,
final String type)
{
}
#Override
public void visitLocalVariable(
final String name,
final String desc,
final String signature,
final Label start,
final Label end,
final int index)
{
}
#Override
public void visitLineNumber(final int line, final Label start) {
}
#Override
public void visitMaxs(final int maxStack, final int maxLocals) {
}
#Override
public void visitMethodEnd() {
}
public void visitAttribute(final Attribute attr) {
}
}
}
and one can run it using:
#Test
public void someTest() throws IOException {
String[] ops = BytecodePrettyPrinter.getMethod("java.lang.String", "<init>", null);
for (String op : ops)
System.out.println(op);
}
In ASM 4, there is a new abstraction called Printer. you can pass your own Printer instance (e.g. extend or copy Textifier implementation) in constructor of the TraceClassVisitor.
The easiest thing I can think of is to use a regex or another type of string matching that filters out just instructions.
For example, use an OutputStreamWriter to write to a String instead. Keep an array of string values of all ASM opcode types, and then if a line in that String contains an opcode string then the line is an instruction.

Categories