Monday, August 23, 2010

Raporu Ziplenmesi ve Zipten Cikarilmasi

Selamun aleykum bugunku yazimda Jasperreports urunu olan IRepor ile olusturdugumuz raporu ziplemem gerekiyordu projede yaptigim bu uygulamayi sizler ile paylasmak istedim. tabi burada bilinmasi gerekenler oncelikler IReport kullanan arkadaslar bilirler platformu oldugu icin cok guzel raporlar olusturmamizi sagliyor hem ucretsiz hemde open source oldugu icin uygulamada istenilen degisiklikler yapilip uygulamaniza ekliyebilirsiniz. IReport report olustururken tamamen bir xml'dir IReportun kendisi bunu .jrxml olarak kaydediyor bizim yapmamiz gereken bu xml okumak ve zip yazmak bu okuma islemini bir cok yolla yapabiliriz ama buraga dikkat edilmesi gerekenler oncelikle raporda bulunan resimleri ve subreportlari dogru bir sekilde alip yazmaktir biz bu uygulamada raporlari zip yazarken isimlerini degistiriyoruz sebebi bilgisayarimizin farkli yerlerinde ayni isimde bulunan resimler , subreport ve reportlar ayni isimde olabilir. Bu isimlerin ayni olabilme ihtimallerinide dusunerekten isimlerini degistiriyoz UUID ile bu sekilde UUID.randomUUID().toString().replaceAll("-", "")    ve okuma islemini yaptiktan sonra zip yaziyoruz gerci kodlar incelerken goreceksinizki cok sade bir yapisi var.
Oncelikle IReport ile reporumuzu olusturdum ben raporumun adini reportEmployee yazdim sonra kediniz istediginiz sikilde dizayn ediyorsunuz raporunuzu ve kaydediyorsunuz..
Simdi gelelim bu yazilan uygulamanin calisma prensibine bu bu uygulamaya oncelile reporun yolunu veriyorsunuz
 File fileReport = new File("d:/reportEmployee.jrxml"); ve daha sonra olusturdugumuz ReportParser class'i devreye girerek raporu aliyor once resim ve subreportlari alim zip yaziyor ve daha sonrada reporun kendisini yaziyor.

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ReportParser {


     
private Properties fileTable;
      private String reportDirectory;
      private File file;
      private ByteArrayOutputStream streamBuffer;
      private ZipOutputStream outputStream;


     
public ReportParser(File file, String reportDirectory) throws Exception {
          this.file = file;
          this.reportDirectory = reportDirectory;
          if (this.reportDirectory == null) {
              this.reportDirectory = file.getParent();
          }

      }

     
public byte[] getContent() {
         return streamBuffer.toByteArray();
     }


     
private String convertToFullName(String directory, String fileName) {
          if (!fileName.contains(File.separator)) {
                 fileName = directory + File.separator + fileName;
          }
          return fileName;
     }


     
public void parse() throws Exception {
        fileTable = new Properties();
        streamBuffer = new ByteArrayOutputStream(1024 * 300);
        outputStream = new ZipOutputStream(streamBuffer);
        parse(file, true);
        outputStream.close();
     }


     
public void parse(File file) throws Exception {
          parse(file, false);
    }


   
private void parse(File file, boolean isMain) throws Exception {

         if (fileTable.getProperty(file.getName()) != null) {
             return;
        }

        String reportName = isMain ? "main.jrxml" : UUID.randomUUID().toString().replaceAll("-", "") + ".jrxml";
        fileTable.setProperty(file.toString(), reportName);
        Document doc = getDocument(file);
        NodeList imgList = doc.getElementsByTagName("imageExpression");
        for (int i = 0; i < imgList.getLength(); i++) {
               Node imgNode = imgList.item(i);
              String fileName = imgNode.getTextContent().replaceAll("\"", "");

              fileName = convertToFullName(file.getParent(), fileName);
              String value = fileTable.getProperty(fileName);

              if (value == null) {
                    value = UUID.randomUUID().toString().replaceAll("-", "") + "." + new File(fileName).getName().split("\\.")[1];
                    fileTable.setProperty(fileName, value);

                   //Image end write
                   ZipEntry entry = new ZipEntry(value);
                   entry.setComment(isMain ? "Main report file" : "Subreport file");
                   outputStream.putNextEntry(entry); //
                   FileInputStream imageInput = new FileInputStream(fileName);

                   byte[] imageBytes = new byte[imageInput.available()];
                   imageInput.read(imageBytes);
                   outputStream.write(imageBytes);
             }
             imgNode.getFirstChild().setNodeValue("\"" + value + "\"");

      }
      NodeList subReportList = doc.getElementsByTagName("subreportExpression");
      for (int i = 0; i < subReportList.getLength(); i++) {
               Node subReportNode = subReportList.item(i);
               String fileName = subReportNode.getFirstChild().getNodeValue().replaceAll("\"", "").replaceAll(".jasper", ".jrxml").replaceAll("\\$P\\{SUBREPORT_DIR\\} \\+ ", "");
               fileName = convertToFullName(file.getParent(), fileName);
                String value = fileTable.getProperty(fileName);
                        if (value == null) {
                              parse(new File(fileName));
                        }
               value = fileTable.getProperty(fileName);
               subReportNode.getFirstChild().setNodeValue("\"" + value.replaceAll("jrxml","jasper") + "\"");
        }
       ZipEntry entry = new ZipEntry(reportName);
       entry.setComment(isMain ? "Main report file" : "Subreport file");
       outputStream.putNextEntry(entry);
       TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), new              StreamResult(outputStream));

   }

    private Document getDocument(File xmlFile) throws Exception {
          DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
          DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
          Document doc = dBuilder.parse(xmlFile);

         doc.getDocumentElement().normalize();
         return doc;
    }

   
public Properties getFileTable() {
        return fileTable;
    }


   
public void setFileTable(Properties fileTable) {
         this.fileTable = fileTable;
     }

}


public class MainTest{
       public static void main(String args[]){
               File fileReport = new File("d:/reportEmployee.jrxml"); 
               FileOutputStream fout = null;
               File fileZip = new File("d:/Deneme.zip");
               ReportParser parser = new ReportParser(fileReport, null);
               parser.parse();
               byte[] content = parser.getContent();
               fout = new FileOutputStream(fileZip);
               fout.write(content);

      }



Asagidaki kod ile reporumuzu zipten cikariyoruz bu kod bilinen zipten cikarma islemi onun icin anlatmaya ihtiyac duymadim

 public class UnZipMain{
         public static void main(String args[]){
            try{ 
                 File file = new File("D:/Deneme.zip");
                 File unZipfile;
                 BufferedOutputStream dest = null;
                 FileInputStream fis = new FileInputStream(file);
                 ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
                 ZipEntry entry;
                 while ((entry = zis.getNextEntry()) != null) {

                           int count;
                           byte data[] = new byte[BUFFER];
                           unZipfile = new File("D:/Reports/");
                           FileOutputStream fos = new FileOutputStream(unZipfile + "/" + entry.toString());
                           dest = new BufferedOutputStream(fos, BUFFER);
                           while ((count = zis.read(data, 0, BUFFER)) != -1) {
                                  dest.write(data, 0, count);
                          }
                          dest.flush();
                          dest.close();
 

                 }
                 zis.close();
             }catch (Exception e) {
                     e.printStackTrace();
            }

         }
}

Thursday, August 12, 2010

Degiskenler(Variables)

Iyi gunler daha onceki yazinda Primitives Type(Ilkel Veri Tipleri) konusunda degisken konusuna biraz deginmistim veri tiplerinin neler oldugu araliklar default aldigi degerler ve Wrapper Class ne oldu ile ilgili bilgilere bilgimizin yetigi kadar deginmistik. Bu bolumde degiskenin tipleri degiskenin nerede var oldugu ve degiskenin ne zamana kadar varligini surdurduyu konusunu ele alacam.

Esasen javada degiskenler temel veri tipleri olarak adlandirirlirlar. Bu anlamda javada iki veri tipi oldugun soyleye bilirirz
  • Primitif tip(Degiskenleri tanimlamak icin kullanilir)
  • Referans tip(Nesneleri tanimlamak icin kullanilir)
Javada uc tur degisken turu var.
  • Local Variables(Yerel degiskenler)
  • Instance Variables(Anlik degiskenler)
  • Class Variables(Sinif degskenler)
Local Variables(Yerel degiskenler) : Yerel değişkenler bir metodun iç değişkenleridir (parametreleri değil). Yerel değişkenler için şu kurallar geçerlidir: 
  • Metot çağrıldığında bellekte kendilerine birer yer açılır
  • Metodun işi bitince, yerel değişkenler de bellekten silinir 
  • Metodun her çağrılışında, her yerel değişkene yeniden yer açılır
  • Yerel değişkenlere yalnızca ait oldukları metot erişebilir
Instance Variables(Anlik degiskenler) : Anlık değişkenler, sınıf içinde bildirimi yapılan ve dingin (static) olmayan değişkenlerdir. Anlık değişkenler için şu kurallar geçerlidir:
  • Nesne yaratılırken her anlık değişkene ana-bellekte bir yer açılır.
  • Nesne yokedilince, anlık değişkene açılan yer de yokolur 
  • Her anlık değişkene, her nesne içinde bir ve yalnız bir yer açılır
  • Anlık değişkene erişim, ait olduğu sınıfın verdiği izinle sınırlıdır 
Class Variables(Sinif degskenler) : Sınıf değişkenleri, sınıf tanımında bildirimi yapılan dingin (static) değişkenlerdir. Sınıf değişkenleri için şu kurallar geçerlidir:
  • Program başlayınca bellekte her sınıf değişkenine sabit bir yer açılır 
  • Sınıf değişkenlerine açılan yerler, program bitene kadar etkin kalırlar, ancak program bitince bellekten silinirler
  • Sınıf değişkenleri, program boyunca yalnız bir kez yaratılırlar
  • Sınıf değişkene erişim, ait olduğu sınıfın verdiği izinle sınırlıdır 
final (Sabitler) : program çalışırken değer değiştiremezler. O nedenle, final damgalı değişkene, bildirimi yapılırken (ilk) değeri verilmelidir. Atanan bu ilk değer, program boyunca değişmeden kalır. Öteki değişkenlerden ayırmak için, Java’da final değişkenlerin adları büyük harflerle yazılır.
  •  Local Variables final yapilinca bildirimleri sırasında ilk değerleri atanabileceği gibi, program çalışırkende değerleri atanabilir.
  • Instance Variable final yapilinca bildirimleri sırasında ilk değerleri atanabilir, program çalışırken değerleri atanabilir, constructor içinde değerleri atanabilir.
  • Class Variables final yapilinca  bildirimleri sırasında ilk değerleri atanabilir,   program çalışırken değerleri atanabilir.
Not :  Her durumda, final kullanılmışsa değişkenlere değerler atanmış olmalıdır.

Variable Scope (Etkinlik bloku) : 
  • Bir değişkenin bir blokta etkin olması demek, o bloktaki kodların değişkeni çağırabilmesi demektir. 
  • Başka bir deyişle, her değişkene ana bellekte bir yer açılır. JVM değişkenin ana bellekteki yerini, etkinlik bloku ile birlikte yaratır ve onunla birlikte yokeder. Bloklar { } büyük parantezi içindeki kodlardan oluşur.
  • Her sınıf bir bloktur. Sınıf içinde bildirimi yapılan anlık değişkenler ve statik değişkenler, o sınıf ana bellekte etkin olduğu sürece yaşarlar. Sınıfın işi bitince, JVM ona ayrılan yeri yokeder. Başka bir deyişle, sınıfa ait nesneler için ana bellekte ayrılan yerleri siler. Bellekte o sınıfa ait hiçbir öğe kalmaz. Bu şekilde bellek alanının temizlenmesi Java’da çöp toplayıcı (garbage collection) tarafından yapılır. Çöp toplayıcının temizlediği alan, programın başka blokları tarafından kullanılmaya hazır hale gelir. Bu olgu, koşan programa yeterli bellek alanının yaratılması için önemlidir. Çöp toplayıcı, program koşarken işi biten bütün nesneleri, değişkenleri, metotları silerek, ana bellekte yer açar.  
  • Her metot bir bloktur. Bir metot içinde tanımlanan yerel değişkenler o metot çağrıldığında etkin olurlar. Metodun işi bitince, JVM yerel değişkenlere ayrılan yeri yokeder, yani onu bellekten siler.
  • Bir metot içinde if, while, for, case blokları yer alabilir. Bunlar, o metodun iç blokları sayılır. İç-içe blokların etkinliği içten dışa doğru sıralanır. Herhangi bir iç blokta tanımlanan değişken o iç-blokta etkindir. 



 Primitive Types and Values
A primitive type is predefined by the Java programming language and named by its reserved keyword 
  1.  PrimitiveType:byte , short , int , long , char , float , double , boolean
  2.  NumericType: byte , short , int , long , char , float , double
  3.  IntegralType: one of : byte short int long char
  4.  FloatingPointType: one of : float double






Bu yaziyi yazarken su linkten cok yararlandim zaten bu yazi bu konuyu cok iyi anlatmis. Bende kendime gore bu yaziyi derledim. Timur Karaçay hocamizin eline saglik Yaziyi ayrintili birsekilde okumak icin altaki link kullana bilirsiniz.
http://www.baskent.edu.tr/~tkaracay/ders/prg/java/variable/variables.htm  

Abdulkadir Selcukoglu
Java Developer 
R.I.S.K Company
Azerbaycan/Baku