Kapan Mau Maju

Semua pejabat pemerintahan harusnya mengerti bahwa menjadi seorang pejabat adalah sebuah komitmen besar. Komitmen untuk membawa kemajuan bagi bangsa ini, komitmen untuk mengubah situasi bangsa menjadi lebih baik. A commitment to drive the country to a better place where everyone can live a decent life.

Tapi entah mengapa, rasanya setiap pejabat pemerintahan hanya melihatnya sebagai sebuah pekerjaan saja. Tidak ada inovasi atau terobosan untuk mengubah nasib rakyatnya. Malah sepertinya mereka berusaha untuk tetap membuat semua rakyatnya bodoh supaya gampang dibodoh – bodohin. Yang kaya akan bertambah kaya, yang miskin semakin terpinggirkan!

Entah mengapa pula, rasanya setiap pejabat pemerintahan kerjaannya mengeluh saja. Gaji saya kurang besar, wc saya kurang elit, gedung tempat saya bekerja kurang mewah, mobil dinas saya kurang baru, rumah dinas saja kurang besar.

Kalo gaji kurang besar kenapa ga buka usaha sendiri saja? Buat apa wc elit, emangnya mau tidur di wc (anggota dpr kerjaannya bukan sidang, tapi tidur)? Gedung mewah buat apa kalo pejabatnya ga pernah ada ditempat pada saat dicari – cari? Mobil hanyalah mobil, gunanya hanya untuk membawa anda dari tempat A ke tempat B, ga perlu mobil mewah apalagi kalo mobil mewah itu dibeli dengan uang rakyat yang notabene masih susah cari makan.

Kalo memang tidak sanggup untuk berkomitmen, lebih baik jangan menjadi pejabat lah. Kalo hanya melihat posisi itu sebagai sebuah pekerjaan untuk mencari uang, lebih baik jangan menjadi pejabat lah.

Jadilah pejabat yang bernurani, yang berkomitmen tinggi dan yang siap memajukan bangsa ini!

Tapi kalo melihat realita di lapangan saat ini, pejabat pemda (bali) dan pusat sama saja kelakuannya. Mereka hanya melihatnya sebagai sebuah pekerjaan, sebuah posisi untuk mencari uang untuk dirinya dan kroni – kroninya.

Ah miris memang melihat berita gontok – gontokan di dunia politik Indonesia.

Entah kapan negara ini bakalan bisa maju kalo kalian seperti ini terus. Yang ada malah kita mengalami kemunduran secara teratur. Sedih memang!

El Classico

Dan Barcelona pun akhirnya memenangkan laga semifinal Liga Champion malam ini. Pantaskah El Barca melewati Los Merengues dari dua laga semifinal ini? Saya kira amat sangat pantas sekali.

Saya kira tidak ada yang bisa memungkiri Barcelona tahun ini adalah tim terbaik di dunia.

Xavi dan Iniesta menjadi motor di lini tengah, Villa, Messi dan Pedro menjadi ujung tombak serangan – serangan mematikan yang ditopang oleh Puyol, Pique dan Valdes di belakang dan kiper. Belum lagi tusukan – tusukan mematikan dari sayap kanan oleh Dani Alves.

Yang menjadi polemik disini adalah jalannya pertandingan pertama yang mengundang kontroversi adalah pertandingan pertama antara kedua tim di semifinal Liga Champion seminggu yang lalu. Kartu merah yang diberikan kepada Pepe dianggap menjadi biang kekalahan Madrid dan Jose Moronyo kemudian dengan mulut besarnya membesar – besarkan masalah ini ke media. Jose Moronyo menyinggung bagaiman Pep dan Barcelona selalu dibantu oleh wasit.

Pertanyaannya berapa besar pengaruh wasit ke hasil sebuah pertandingan liga sebesar Liga Champion? Jawabannya tidak signifikan kalo kamu memang good enough. Kalo kamu berpikir wasit bisa mengubah hasil pertandingan, maka itu berarti tim kamu masih not good enough.

Kita harus mengakui bahwa wasit adalah seorang manusia dan manusia membuat kesalahan. Jika wasit membuat satu dua kesalahan, rasanya tidak perlu terlalu berkoar – koar menyalahkan kemana – mana atas kekalahan tim kita *Yep, I’m pointing at you Mr. Special Need One*

Dan dengan hasil imbang antara kedua tim di laga kedua, semua orang akan berpikir Jose Moronyo benar. Kalau saja tidak ada kartu merah, mungkin Madrid bisa lolos ke final.

Well, that’s a big NO NO!

Ada beberapa fakta yang perlu dilihat disini.

Premier League beberapa hari yang lalu, West Brom yang bermain dengan 10 orang pemain bisa mengalahkan Aston Villa. West Brom mencetak gol kedua pada saat mereka bermain dengan 10 orang pemain. Lalu kenapa Madrid tidak bisa melakukannya juga dengan 10 orang mereka? Jawabannya karena mereka not good enough.

Deportivo La Coruna pernah melakukan comeback besar di Liga Champion beberapa tahun yang lalu. Dari ketinggalan 4 – 1, Super Depor membalikkan keadaan 4 – 0 di Riazor. Dan lawannya adalah AC Milan yang saat itu masih diperkuat oleh Sheva dan Kaka. Kenapa Madrid tidak bisa melakukan comeback di Nou Camp? Karena they are not good enough.

Mungkin fakta terbesar adalah fakta dari pertandingan itu sendiri. Fakta dari pertandingan pertama adalah ball possession dari kedua tim. Pertandingan pertama 72% – 28% dan pertandingan kedua 63% – 37%. Dari sini kita lihat bagaimana El Barca mendominasi pertandingan mereka dengan possession football mereka yang menawang.

Shots dan shots on target 8(5) – 6(3) dan 10 (6) – 2 (1). Disini terlihat El Barca kembali mendominasi shot dan shot on target. Di pertandingan kedua Madrid bahkan hanya menghasilkan satu shot on target yang berarti Valdes hanya menjadi pajangan di gawang El Barca. Di pertandingan pertama ini juga kita menyaksikan gol ajaib dari Messi yang diciptakan setelah dia melewati setengah pemain Madrid yang ada di lapangan. Sheer magical stuff from Messi.

Jadi kenapa Jose Moronyo begitu berkoar – koar di media? Menurut saya itu semua untuk menutup – nutupi kesalahan strategi yang dia terapkan di pertandingan pertama. Dia berusaha mengalihkan perhatian semua orang ke hal – hal non – teknis yang terjadi di pertandingan itu (sama seperti penggelembungan kasus – kasus yang terjadi di Indonesia untuk mengalihkan perhatian publik).

Fakta sudah menunjukkan bahwa El Barca adalah tim yang lebih baik by far. Lini belakang Barca yang dikomandani Pique dan Puyol jauh lebih baik daripada lini belakang Madrid. Lini tengah Barca yang dikomandani Xavi dan Iniesta jauh lebih baik daripada lini tengah Madrid. Dan Leo Messi jauuuuuuuuuuuh lebih baik daripada Celeng Ronaldo by far.

Jadi menurut saya, Barca amat sangat pantas sekali lolos ke babak selanjutnya. Sekarang tinggal menunggu pertandingan selanjutnya yang bertajuk Boring Football …

Semoga Barca menjadi juara Liga Champion tahun ini.

Anak Terbaik Bangsa

Weh sudah lama sekali tidak mengupdate blog tercinta ini ternyata. Sementara lagu Kabhi Khushi Kabhi Gham mengalun kencang dari Youtube, marilah kita mengucapkan selamat kepada anak bangsa yang “didaulat” menjadi wakil rakyat (entah rakyat sebelah mana itu) yang sudah berhasil menjadi lebih terkenal di masyarakat. Setidaknya sekarang masyarakat tahu nama salah satu wakil mereka di gedung tua nan reyot yang akan direnovasi dengan uang hasil keringat rakyat itu.

Semua orang menghujat pemikiran anak – anak “terbaik” itu.

Disaat sekolah – sekolah di daerah hampir ambruk, anak – anak “terbaik” bangsa itu merencanakan pembangunan gedung tempat mereka bersidang supaya menjadi gedung mewah. Gedung mewah yang hanya akan ditempati oleh beberapa orang dengan laptop dan tablet pc mereka masing – masing yang sudah dilengkapi dengan koleksi – koleksi Miyabi terbaru ato Ariel – Luna Maya ato Ariel – Cut Tari. Gedung mewah yang hanya akan ditempati oleh beberapa orang karena sebagian besar dari anak – anak “terbaik” bangsa itu melakukan “study banding” ke luar negeri untuk melihat arsitektur mall – mall atau pusat perbelanjaan di Eropa ato Amerika.

Sedih? Miris? Ato malah optimis arsitektur mall dan pusat perbelanjaan itu bisa diterapkan untuk membangun sekolah – sekolah di daerah?

Semoga Tuhan bisa memaafkan jiwa – jiwa anak – anak “terbaik” bangsa yang sudah jauh tersesat ini.

Altering Execution Flow

Dengan menggunakan mekanisme try catch sebuah exception, kita bisa bikin eksekusi code kita melompat – lompat sesuai keinginan kita. Ini biasanya kita gunakan untuk sanity check dari variable yang kita punya.

Contohnya adalah code berikut ini (penjelasannya ada di comment dari method berikut ini):

protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object object, BindException bindException) throws Exception {
    // user must be authenticated (avoids auth errors)
    if (Context.isAuthenticated()) {
        HttpSession httpSession = request.getSession();
        httpSession.setMaxInactiveInterval(-1); // don't let the session expire

        String password = ServletRequestUtils.getStringParameter(request, "password");
        String passphrase = ServletRequestUtils.getStringParameter(request, "passphrase");

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

        byte[] iv = new byte[IV_SIZE];
        try {
            MultipartFile secretFile = multipartRequest.getFile("secretFile");
            // sanity check
            if (secretFile == null || secretFile.isEmpty())
                throw new IOException("Unable to read secret file.");
            InputStream secretFileInputStream = secretFile.getInputStream();
            int ivSize = secretFileInputStream.read(iv);
            // make sure the iv is 16 byte
            if (ivSize != IV_SIZE)
                throw new IOException("Secret file is corrupted or invalid secret file are being used.");
            secretFileInputStream.close();

            MultipartFile returnedData = multipartRequest.getFile("summaries");
            // sanity check
            if (returnedData == null || returnedData.isEmpty())
                throw new IOException("Unable to read collection of summaries file.");
            InputStream summariesInputStream = returnedData.getInputStream();

            FileUtils.inflateSummaries(summariesInputStream, SummaryConstants.OUTPUT_LOCATION, password, passphrase, iv);
            FileUtils.loadIndexFile("summaryindex.sql");

            summariesInputStream.close();

            String message = "Inflating collection of summary files completed successfully. Please check if files are decrypted succesfully.";
            httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, message);
        }
        catch (Exception e) {
            log.error("Inflating collection of summary files failed", e);
            httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, e.getMessage());
        }
        return new ModelAndView(new RedirectView(getSuccessView()));
    }
    return showForm(request, response, bindException);
}

Inti dari tips kali ini adalah throwing exception didalam try catch block. Dengan mekanisme ini, flow dari program kita akan berubah sesuai dengan exception yang terjadi. Contohnya saat ivSize yang dibaca tidak sesuai dengan minimum yang kita inginkan, kita bisa men-throw exception disana dan exception ini akan di-catch kemudian sebuah error message akan ditampilkan di halaman web yang sedang dibuka oleh user.

            if (ivSize != IV_SIZE)
                throw new IOException("Secret file is corrupted or invalid secret file are being used.");

Dengan mekanisme ini, kita bisa mengatur flow eksekusi program kita tanpa if-then-else dan tanpa explicit goto.

Tomcat Streaming

Ah mari kita pindah topik sedikit ke masalah coding. Waktu ini saya diminta membuat halaman untuk mengelola file clinical summary dari 180 ribu patient. Wah bingung juga gimana coding-nya untuk nge-download 1.5GB data itu. Yang jelas data itu harus di-stream, karena kalo di-buffer semuanya terus dimuntahin sekaligus ke user, dijamin si server bakalan tewas dengan sukses. Damn, masak mesti baca – baca wikipedia lagi seh … Dan akhirnya nyangkut kesini deh Content Disposition. Oh ternyata itu toh yang dipakai biar user dikasi window save as itu ya.

        // -- Java codenya
        // --- response: adalah HttpServletResponse object
        // --- filename: nama file
        // --- zippedFile: pointer ke file yang akan di stream

        response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".zip");
        response.setContentType("application/zip");
        response.setContentLength((int) zippedFile.length());
        response.flushBuffer();

Lalu streaming e gimana? Bleh tambah pusing dah. Ternyata pake NIO lebih enak kalo streaming itu hehehe … Ga tau seh apakah pake yang IO biasa bakalan jalan ato ga. Harusnya sih jalan – jalan aja lah ya si basic IO. Intinya seh baca sedikit demi sedikit terus tulisin di buffer e si response hehehe …

        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(zippedFile));
        ReadableByteChannel input = Channels.newChannel(inputStream);
        WritableByteChannel output = Channels.newChannel(response.getOutputStream());
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);</code>

        while (input.read(buffer) != -1) {
            buffer.flip();
            output.write(buffer);
            buffer.clear();
        }

        input.close();
        output.close();

Dan setelah di test, data 1.5GB pun ter-stream dengan sukses tanpa membunuh server tercinta. Berikutnya pusing – pusing bersama Java Cryptography Extension. Yah, mereka pengennya kan data yang bakalan dipindahin ini terenkripsi dengan sukses supaya kalo ada yang nyegat yang bawa data, dia ga bisa dapat isi datanya dengan mudah hehehe …