1.3 Диаграмма классов
на рисунке 1.1 изображена диаграмма класов
Рисунок 1.1 - Диаграмма классов
1.3 Исходные тексты классов
MainGui
package lab1java_tehn;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.Annotation;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
public class MainGUI {
JFrame frame;
JTree tree;
DefaultListModel<String> modelMethods,modelFields,modelConstructors;
JList<String> listMethods,listJields,listConstructors;
JScrollPane scrollPane;
JTextPane textPane;
JarFile jarFile;
File selectedFile=null;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainGUI window = new MainGUI();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainGUI() {
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
initialize();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initialize() throws IOException {
frame = new JFrame();
frame.setBounds(100, 100, 923, 629);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
modelMethods=new DefaultListModel<String>();
modelFields=new DefaultListModel<String>();
modelConstructors=new DefaultListModel<String>();
JButton btnNewButton = new JButton("\u0412\u044B\u0431\u0440\u0430\u0442\u044C .jar");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
onClickSelectFile();
}
});
scrollPane = new JScrollPane();
scrollPane.setBounds(10, 45, 340, 360);
frame.getContentPane().add(scrollPane);
btnNewButton.setBounds(10, 11, 340, 23);
frame.getContentPane().add(btnNewButton);
JLabel label = new JLabel("\u041C\u0435\u0442\u043E\u0434\u044B");
label.setBounds(360, 15, 158, 14);
frame.getContentPane().add(label);
JLabel lblNewLabel = new JLabel("\u041F\u043E\u043B\u044F");
lblNewLabel.setBounds(541, 15, 171, 14);
frame.getContentPane().add(lblNewLabel);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(360, 45, 171, 360);
frame.getContentPane().add(scrollPane_1);
listMethods = new JList<String>(modelMethods);
scrollPane_1.setViewportView(listMethods);
JScrollPane scrollPane_2 = new JScrollPane();
scrollPane_2.setBounds(541, 45, 171, 360);
frame.getContentPane().add(scrollPane_2);
listJields = new JList<String>(modelFields);
scrollPane_2.setViewportView(listJields);
JScrollPane scrollPane_3 = new JScrollPane();
scrollPane_3.setBounds(722, 45, 171, 360);
frame.getContentPane().add(scrollPane_3);
listConstructors = new JList<String>(modelConstructors);
scrollPane_3.setViewportView(listConstructors);
JLabel lblNewLabel_1 = new JLabel("\u041A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0440\u044B");
lblNewLabel_1.setBounds(722, 15, 171, 14);
frame.getContentPane().add(lblNewLabel_1);
JScrollPane scrollPane_4 = new JScrollPane();
scrollPane_4.setBounds(10, 416, 883, 163);
frame.getContentPane().add(scrollPane_4);
textPane = new JTextPane();
scrollPane_4.setViewportView(textPane);
}
public void clearAllViews(){
modelMethods.clear();modelFields.clear();modelConstructors.clear();
textPane.setText("");
}
public TreeSelectionListener treeSelectionListener(){
TreeSelectionListener listener=new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
new Thread(new Runnable() {
public void run() {
MyNode tr=(MyNode) tree.getLastSelectedPathComponent();
clearAllViews();
if(tr.getObject()!=null){
Class<?> c=(Class<?>) tr.getObject();
if(c!=null){
Method[] metods=c.getDeclaredMethods();
for(Method m:metods){
modelMethods.addElement(Utils.printModifiers(m.getModifiers())+m.getReturnType()+" "+m.getName());;
}
Field[] fields=c.getDeclaredFields();
for(Field f:fields){
modelFields.addElement(Utils.printModifiers(f.getModifiers())+f.getType()+" "+f.getName());
}
Constructor<?> [] constructors=c.getDeclaredConstructors();
for(Constructor<?> cons:constructors){
modelConstructors.addElement(Utils.printModifiers(cons.getModifiers())+" "+cons.getName());
}
}
}
else{
JarEntry j=tr.getJarEntry();
if(j==null)return;
String info=j.getName()+"\nРазмер "+j.getSize()+" байт\nДата модификации "+j.getLastModifiedTime();
String type=Utils.getType(j.getName()); info+="\nТип файла: "+type;
if(type.equals("Текст")){
try {
InputStream inputStream = jarFile.getInputStream(j);
info+="\n\nСодержимое файла:\n"+Utils.getLinesOfJar(inputStream);
} catch (IOException ioException) {
info+="\n\nError read " + j.getName();
}
}
textPane.setText(info);
}
}
}).start();;
}
};
return listener;
}
public void onClickSelectFile(){
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JAR файлы", "jar");
chooser.setFileFilter(filter);
chooser.setDialogTitle("Выберите JAR для анализа");
int returnVal = chooser.showOpenDialog(frame);
if(returnVal == JFileChooser.APPROVE_OPTION) {
selectedFile=chooser.getSelectedFile();
if(!selectedFile.getName().contains(".jar")){
JOptionPane.showMessageDialog(frame, "Это не Jar файл!","Ошибка",JOptionPane.ERROR_MESSAGE);
return;
}
tree=new JTree(new MyNode(selectedFile.getAbsolutePath(),"xz",null,null));
scrollPane.setViewportView(tree);
tree.addTreeSelectionListener(treeSelectionListener());;
tree.expandPath(new TreePath(tree.getModel().getRoot()));
new Thread(new Runnable() {
@Override
public void run() {
try{
xzclass();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
else{
JOptionPane.showMessageDialog(frame, "Не выбран файл!","Ошибка",JOptionPane.ERROR_MESSAGE);
}
}
public void xzclass() throws IOException {
System.out.println(selectedFile.getAbsolutePath());
ClassLoader loader = new MyClassLoader(selectedFile.getAbsolutePath());
jarFile = new JarFile(selectedFile.getAbsolutePath());
Enumeration<JarEntry> enumiration = jarFile.entries();
String s; Class<?> c = null; JarEntry e;
addNewItem("META-INF",null,null);
while(enumiration.hasMoreElements()){
e = enumiration.nextElement();
if(e.isDirectory()){addNewItem(e.getName(),e,null);}
if (e.getName().contains(".class")) {
s = e.getName().replaceAll("/", ".");
s = s.substring(0, s.length()-6);
boolean isErr=false;
try{
c = Class.forName(s, false, loader);
}catch(ClassNotFoundException e2){
System.out.println("Error:"+e2.getMessage());
isErr=true;
}
if (!isErr&&c!=null){addNewItem(e.getName(),e,c);}
}else{
if(!e.isDirectory())addNewItem(e.getName(),e,null);
}
}//jarFile.close();
}
public void addNewItem(String name,JarEntry current,Object object){
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
MyNode sel=null;
String []data=name.split("/");
if(data.length>1)sel=findUserObject(data[data.length-2],data);
MyNode tmp = new MyNode(data[data.length-1],name,current,object);
if(sel==null)sel=(MyNode)tree.getModel().getRoot();
model.insertNodeInto(tmp, sel, sel.getChildCount());
tree.expandPath(new TreePath(model.getRoot()));
}
private MyNode findUserObject(Object obj,String[] arr){
ArrayList<MyNode> findList=new ArrayList<>();
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
MyNode rootNode = (MyNode)model.getRoot();
Enumeration<?> enumeration = rootNode.breadthFirstEnumeration();
while (enumeration.hasMoreElements()){
MyNode node = (MyNode)enumeration.nextElement();
if(node.getPathName().contains(obj.toString())){
findList.add(node);
}
}
for(MyNode xz:findList){
String []splits=xz.getPathName().split("/");
if(splits[0].equals(arr[0])){
return xz;
}
}return null;
}
}
MyClassLoader
package lab1java_tehn;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class MyClassLoader extends ClassLoader {
private String jarName;
private JarFile jar;
@SuppressWarnings("rawtypes")
private Map<String, Class> loaded = new HashMap<String, Class>();
public MyClassLoader(String jarName) {
super(MyClassLoader.class.getClassLoader());
this.jarName = jarName;
try {
this.jar = new JarFile( jarName );
} catch (IOException e) {
e.printStackTrace();
}
}
public Class<?> findClass(String name) throws ClassNotFoundException{
Class<?> c = loaded.get(name);
if (c!=null)return c;
try{
return findSystemClass(name);
}catch(Exception e){
}
byte[] b;
try{
b = loadClassData(name);
c=defineClass(name, b, 0, b.length);
loaded.put(name, c);
}catch(Throwable e){
// throw new ClassNotFoundException(e.getMessage());
System.err.println("Class "+name+" not found!");
return null;
}return c;
}
private byte[] loadClassData(String name) throws ClassNotFoundException {
String entryName = name.replace('.', '/') + ".class";
byte buf[]=new byte[0];
try {
JarEntry entry = jar.getJarEntry(entryName);
if (entry==null){
throw new ClassNotFoundException(name);
}
InputStream input = jar.getInputStream( entry );
int size = new Long(entry.getSize()).intValue();
buf = new byte[size];
int count = input.read(buf/*, 0, size*/);
if (count < size)
throw new ClassNotFoundException("Error reading class '"+name+"' from :"+jarName);
} catch (IOException e1) {
throw new ClassNotFoundException(e1.getMessage());
}
return buf;
}
}
MyNode
package lab1java_tehn;
import java.util.jar.JarEntry;
import javax.swing.tree.DefaultMutableTreeNode;
@SuppressWarnings("serial")
public class MyNode extends DefaultMutableTreeNode{
private JarEntry jarEntry;
private String name;
private Object object;
private String pathName="/";
public MyNode(String name,String pathName,JarEntry jarEntry,Object object){
setUserObject(name);
this.name=name;
this.pathName=pathName;
this.jarEntry=jarEntry;
this.object=object;
}
public Object getObject(){
return this.object;
}
public JarEntry getJarEntry(){
return this.jarEntry;
}
public String getName(){
return this.name;
}
public String getPathName(){
return this.pathName;
}
}
Utils
package lab1java_tehn;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Modifier;
public class Utils {
public static String getLinesOfJar(InputStream input) throws IOException{
String result="";
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null)
result+=line+"\n";
reader.close();
return result;
}
public static String printModifiers(int m) {
String result="";
if (Modifier.isPublic(m)) result+="public ";
if (Modifier.isPrivate(m)) result+="private ";
if (Modifier.isProtected(m)) result+="protected ";
if (Modifier.isVolatile(m)) result+="volatile ";
if (Modifier.isTransient(m)) result+="transient ";
if (Modifier.isAbstract(m)) result+="abstract ";
if(Modifier.isStatic(m))result+="static ";
if(Modifier.isFinal(m))result+="final ";
return result;
}
public static String getType(String s){
if(s.contains(".jpg")||s.contains(".gif")||s.contains(".png")||s.contains(".GIF"))return "Изображение";
if(s.contains(".txt")||s.contains(".xml")||s.contains(".htm")||s.contains(".html"))return "Текст";
if(s.contains(".wav")||s.contains(".mp3"))return "Звук";
else return "Неизвестный тип";
}
}
Выводы
В данной лабораторно й работе мы разработали программу для динамической загрузки классов. Также мы вспомнили некоторые моменты с прошлого семестра и воспользуясь своими знаниями мы создали программу для откривания jar файлов.