import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

import java.io.*;

import java.util.*;  // ArrayList


import javax.xml.bind.annotation.*;
import javax.xml.bind.*;


// schreiben und lesen von CAuto
//   Format XML, mittel xml.bind.annotation
//   das Root bekommt ein Element vor der Klassendefintion
//    alle Klassen muessen einen Default-Kontruktor haben !!!!!!!!!!!!!

//    es muessen alle get und set-Methoden implementiert werden  !!!!!!!!

// schreiben und lesen von CAutos (Garage)
//   Format XML, mittel xml.bind.annotation

public class klassen_read_write5 extends JFrame {

  JButton Bn1 = new JButton("write Auto XML");
  JButton Bn2 = new JButton("lesen Auto XML");
  JButton Bn3 = new JButton("write Garage XML");
  JButton Bn4 = new JButton("lesen Garage XML");
  JButton BnOk = new JButton("Ok");
  JButton BnEsc = new JButton("Abbruch");


  private JTextArea editor;


  public klassen_read_write5() {
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setGUI();
  }

  private void setGUI() {
    setSize(800, 430);
    setTitle("Serialize load and save");

    Bn1.setFont( new Font("Arial", Font.BOLD,16)  );
    Bn2.setFont( new Font("Arial", Font.BOLD,16)  );
    Bn3.setFont( new Font("Arial", Font.BOLD,16)  );
    Bn4.setFont( new Font("Arial", Font.BOLD,16)  );
    BnOk.setFont( new Font("Arial", Font.BOLD,16)  );
    BnEsc.setFont( new Font("Arial", Font.BOLD,16)  );
    BnOk.setPreferredSize( BnEsc.getPreferredSize() );

    this.getContentPane().setLayout( new BorderLayout() );
    editor = new JTextArea("editor");
    editor.setFont( new Font("Arial", Font.BOLD,18)  );
    this.getContentPane().add( new JScrollPane(editor), BorderLayout.CENTER);

	JPanel pnButton = new JPanel();
	//pnButton.setBackground(Color.red);
	pnButton.setLayout( new FlowLayout() );
	pnButton.add(Bn1);
	pnButton.add(Bn2);
	pnButton.add(Bn3);
	pnButton.add(Bn4);
	pnButton.add(BnOk);
	pnButton.add(BnEsc);

    this.getContentPane().add( pnButton, BorderLayout.SOUTH );

          Bn1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              Bn1_Click();
            }
          });
          Bn2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              Bn2_Click();
            }
          });

          Bn3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              Bn3_Click();
            }
          });
          Bn4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              Bn4_Click();
            }
          });

          BnOk.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnOk_Click();
            }
          });


          BnEsc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnEsc_Click();
            }
          });


  } // setGUI

    // speichert zwei Autos in unterschiedlichen XML-Dateien
   private void Bn1_Click() {
    CAuto a1 = new CAuto("VW Golf", "WR HS 1234", 4, 120, 4);
    CAuto a2 = new CAuto("Renault Megane", "MD RN 4321", 2, 120, 4);

    JAXBContext jc=null;
    FileOutputStream fout=null;
    Marshaller msh;
    try {
      editor.setText("schreiben\n");
      editor.append( a1.toString() );
      editor.append( a2.toString() );

      fout = new FileOutputStream("auto1.xml");
      jc = JAXBContext.newInstance(CAuto.class);
      msh = jc.createMarshaller();
      msh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      msh.marshal( a1, System.out);
      msh.marshal(a1,fout);
      fout.close();

      fout = new FileOutputStream("auto2.xml");
      jc = JAXBContext.newInstance(CAuto.class);
      msh = jc.createMarshaller();
      msh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      msh.marshal( a2, System.out);
      msh.marshal(a2,fout);
      fout.close();
    }
    catch (IOException e1) {
        System.err.println("IOException: " + e1);
    }    
    catch (JAXBException e2) {
        System.err.println("JAXBException: " + e2);
    }    
   }  // Bn1

    // laedt zwei Autos aus unterschiedlichen XML-Dateien
   private void Bn2_Click() {
     CAuto a1;
     CAuto a2;
     JAXBContext context;
     Unmarshaller umsh;
     try {
         editor.setText("lesen von auto1.xml und auto2.xml\n");
         context = JAXBContext.newInstance( CAuto.class );
         umsh = context.createUnmarshaller();
         a1 = (CAuto) umsh.unmarshal( new FileReader( "auto1.xml" ) );
         editor.append( a1.toString() );

         context = JAXBContext.newInstance( CAuto.class );
         umsh = context.createUnmarshaller();
         a2 = (CAuto) umsh.unmarshal( new FileReader( "auto2.xml" ) );
         editor.append( a2.toString() );
    }
    catch (FileNotFoundException e1) {
        System.err.println("FileNotFoundException: " + e1);
    }
    catch (JAXBException e2) {
        System.err.println("JAXBException: " + e2);
    }
   }  // Bn2


    // speichert zwei Autos mittels einer Liste in einer XML-Datei
   private void Bn3_Click() {
    CAutos liste = new CAutos();
    CAuto a1 = new CAuto("VW Golf", "WR HS 1234", 4, 120, 4);
    CAuto a2 = new CAuto("Renault Megane", "MD RN 4321", 2, 120, 4);
    JAXBContext jc=null;
    FileOutputStream fout=null;
    Marshaller msh;
    try {
      liste.add(a1);
      liste.add(a2);
      editor.setText("schreiben aus Liste\n");
      editor.append( a1.toString() );
      editor.append( a2.toString() );

      fout = new FileOutputStream("autos.xml");
      jc = JAXBContext.newInstance( CAutos.class);
      msh = jc.createMarshaller();
      msh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      msh.marshal( liste, System.out);
      msh.marshal(liste,fout);
      fout.close();

    }
    catch (IOException e1) {
        System.err.println("IOException: " + e1);
    }    
    catch (JAXBException e2) {
        System.err.println("JAXBException: " + e2);
    }    
   }  // Bn3


    // laedt zwei Autos mittels einer Liste aus einer XML-Datei
   private void Bn4_Click() {
     CAutos liste;
     JAXBContext context;
     Unmarshaller umsh;
     try {
         editor.setText("lesen von autos.xml\n");
         context = JAXBContext.newInstance( CAutos.class );
         umsh = context.createUnmarshaller();
         liste = (CAutos) umsh.unmarshal( new FileReader( "autos.xml" ) );
         editor.append( liste.toString() );
    }
    catch (FileNotFoundException e1) {
        System.err.println("FileNotFoundException: " + e1);
    }
    catch (JAXBException e2) {
        System.err.println("JAXBException: " + e2);
    }
   }

    private void BnOk_Click() {
        System.out.println("Hier in Ok");
        System.exit(0);
    }

    private void BnEsc_Click() {
        setVisible(false);
        System.exit(0);
    }


  public static void main(String[] args) {
    klassen_read_write5 frame = new klassen_read_write5();
    frame.setVisible(true);
 }

}  // klassen_read_write1


@XmlRootElement( name="autos")
@XmlSeeAlso({CAuto.class})  // wird benoetigt, da sonst xml nicht CAuto kennt
class CAutos  {
   private LinkedList liste = new LinkedList();

   public CAutos () {
   }

   public void add(Object obj) {
    liste.add(obj);
   }

   @XmlElement(name="auto")  // sonst ist der Name liste
   public LinkedList getliste() {
     return liste;
   }
   public void setliste(LinkedList liste) {
     this.liste=liste;
   }

   public String toString() {
     String sValue="";
     for (int i=0; i<liste.size(); i++) {
       Object obj = liste.get(i);
       sValue+= obj.toString()+"\n";
      }
     return sValue;
   }

} // CAutos


// dieses Root gilt für einzelne Autos
@XmlRootElement( name="auto")
class CAuto {
   @XmlElement(name="version")
   final int C_VERSION =1;

   private CMotor motor;
   private String sname;
   private String skfz;
   private int anzTueren;


   public CAuto () {
     this("","",0,0,0);
   }
   public CAuto (String sname, String skfz, int anzTueren, int ps, int zylinder) {
     this.sname = sname;
     this.skfz = skfz;
     this.anzTueren = anzTueren;
     motor = new CMotor(ps,zylinder);
   }


   @XmlElement(name="name")
  public String getsname() {
    return sname;
  }
  public void setsname(String sname) {
    this.sname=sname;
  }


   @XmlElement(name="kfz")
  public String getskfz() {
    return skfz;
  }
  public void  setskfz(String skfz) {
    this.skfz=skfz;
  }

   @XmlElement(name="anztueren")
  public int getanzTueren() {
    return anzTueren;
  }
   // 
  public void setanzTueren(int anztueren) {
    this.anzTueren=anztueren;
  }


   @XmlElement(name="motor")
  public CMotor getMotor() {
    return motor;
  }


  public void setMotor(CMotor motor) {
    this.motor=motor;
  }


   public String toString() {
    return "Name: "+sname+"  KFZ: "+skfz+"  anzTüren: "+anzTueren+"\n";
   }
} // CAuto



class CMotor {
   private int ps;
   private int zylinder;

    //  SEHR WICHTIG
    // XML erzeugt das Objekt und setzt die Attribute !!!
   public CMotor () {
     this(0,0);
   }

   public CMotor (int ps, int zylinder) {
     this.ps = ps;
     this.zylinder = zylinder;
   }

   @XmlElement(name="ps")
  public int getps() {
    return ps;
  }
  public void setps(int ps) {
    this.ps=ps;
  }


   @XmlElement(name="zylinder")
  public int getzylinder() {
    return zylinder;
  }
  public void setzylinder(int zylinder) {
    this.zylinder=zylinder;
  }

} // CMotor


