Pesquisa personalizada

2010/01/30

TIM 3G Ilimitado: EhLimitado, mesmo!!!

Abaixo, resposta oficial da TIM à reclamação que fiz via web pela seção de atendimento no website da própria TIM. Trata-se da picaretagem de venderem um plano que dizem ser ilimitado, mas que na verdade eles limitam a velocidade. Pior: como eu não sabia, acabei-me fidelizando num pacote de dados de 1Mbs!!!! Só agora, quando precisei, é que soube que eles limitavam. Quando fui realizar a comprar, apesar de ter questionado se havia algum tipo de limitação tráfego, a atendente da TIM (loja da TIM do ParkShopping de Brasília) disse que não havia nenhum tipo de limitação..

Meu Questionamento

Prezados(as),
   Até cerca de duas semanas atrás, estava muito satisfeito com plano Infinity 160 + 1Mbs de dados **** I LI M I T A D O ***. Uso a conexão de dados constantemente no trabalho, mas apenas para realizar pequenos acessos a e-mail e notícias - fazendo pouco download de arquivos. No entanto, este mês fiquei sem provedor em minha residência e fui obrigado a usar internet utilizando meu plano da TIM (meu celular é o Nokia 5800 XPM que adquiri num plano fidelidade com a TIM); fiz muitos downloads, possivelmente alguns gigabytes fora baixados. Neste fim de semana, me dei conta que minha conexão de dados 3G, que sempre funcionou muito bem, como eu já disse antes, agora não funciona a velocidade plena. Estou nos mesmos lugares que sempre estive, ou seja, nos mesmos lugares que sempre tiveram cobertura UMTS 3G e que antes alcança com facilidade velocidades de até 139Kbytes/s, mas que agora não passa de 23Kbytes/s com raros (menos de 0.01% do tempo) picos de exceção.
Dessa forma, gostaria que a TIM me informasse se ela impõe algum tipo de limite de velocidade quando o cliente ultrapasse alguma quantidade de dados trafegados (download ou upload). A TIM impõe essa limitação? Se faz, a partir de quantos GB (Gigabytes) trafegados? Se não impõe limite, por que não consigo mais obter as mesmas velocidades de antes se meu plano é de 1Mbs?!!!
Aguardo retorno.

Grato,
Marcio Wesley Borges
marciowb[*]gmail.com
(61) 8211-5400 / (61) 3xxx-xxxx

--------------------------------

Protocolo da TIM (auto atendimento via web)

Obrigado por entrar em contato com a TIM.
Sua mensagem foi enviada com sucesso e você receberá uma resposta em no máximo 2 dias úteis. Por favor, anote o número do seu chamado:

2010014653061

Resposta da TIM

Protocolo 2010014653061

Prezado Sr. Marcio

Conforme clausula 17 do termo de compromisso: Para todos os Pacotes após o consumo de 1GB, a TIM poderá, a seu exclusivo critério, reduzir a velocidade até o período de faturamento subseqüente.

Atenciosamente,      
Maria Ester
Central de Relacionamento com Clientes  
www.tim.com.br                                                     
Por favor, não responda esta mensagem. Caso necessário, envie uma nova mensagem através de nosso site TIM.

================================================================================

Cliente - Consumidor
Nome: MARCIO WESLEY BORGES
CPF/CNPJ: XXXXXXXXXXXXX
Administrador de contrato: não
Telefone: 06182115400
E-Mail: marciowb[*]9mail.com
Estado: DF
Tipo: Informação
Assunto: Serviços Avançados

Anatel e Ministério Público

Cadê a Anatel nessas horas?! Cadê o ministério público? A realidade é que já faz tempo que estamos desamparados. No Brasil, falou em telecoms, bancos e consumidor, somente os dois primeiros exercem (e usurpam!!!) seus direitos. Vamos protestar!!

Ainda nesta semana, após o ministério público resolver trabalhar, a Claro foi condenada por não entregar o devido serviço 3G que se contrata.

Labels: , , ,

2009/11/07

Icefaces+Facelets: Customizing the basic html (XHTML) tags using a simple Render Kit extension

Alright, the life, at least my life, isn't easy. But after fourteen hours, finally, I know how to do a simple task: insert the xmlns attribute into the final code of the html tag generated by Icefaces+Facelets couple.

I know that are several ways to insert this attribute, but I just want to play it using the JSF Render Kit. I don't want to filter the stream, or output the tag, or anything else. The render kit should be the way.

I just want to write:
   1:<?xml version='1.0' encoding='UTF-8' ?> 
   2:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   3:<html xmlns="http://www.w3.org/1999/xhtml"
   4:      xmlns:ui="http://java.sun.com/jsf/facelets"
   5:      xmlns:c="http://java.sun.com/jstl/core"
   6:      xmlns:h="http://java.sun.com/jsf/html"
   7:      xmlns:ice="http://www.icesoft.com/icefaces/component"
   8:      >
   9:    <body>
  10:
  11:        <ui:composition template="/WEB-INF/tmp/template.xhtml">
  12:
  13:            <ui:param name="hasLeftSection" value="false"/>
  14:            <ui:param name="pageDescription" value="${ArtistPage.pageDescription}"/>
  15:
  16:            <ui:define name="pageTitle">${ArtistPage.pageTitle}</ui:define>
  17:            <ui:define name="extraHeader">
  18:                <link rel="canonical" href="${ArtistPage.canonicalUrl}" />
  19:            </ui:define>
  20:
  21:            <ui:define name="body">
But the xmlns="http://www.w3.org/1999/xhtml" attribute is always trimmed by icefaces/facelets (maybe it's a simple thing to configure using com.icesoft.faces.facelets.D2DFaceletViewHandler or com.sun.facelets.compiler.Compiler - But I didn't investigate them to know).

I inspected the Icefaces code and I saw that it uses the renderer from com.icesoft.faces.renderkit.dom_html_basic.XMLRenderer to write out (to render) the most xhtml tags, like html, body, head, title etc. So, after a little test, was easy to write my own render to add the attribute that I need (or any other, also). The render code is:

   1:package com.solvoj.sondaletra.faces;
   2:
   3:import com.icesoft.faces.component.UIXhtmlComponent;
   4:import com.icesoft.faces.renderkit.dom_html_basic.XMLRenderer;
   5:import java.io.IOException;
   6:import java.util.Iterator;
   7:import java.util.Map;
   8:import javax.faces.component.UIComponent;
   9:import javax.faces.context.FacesContext;
  10:import javax.faces.context.ResponseWriter;
  11:
  12:/**
  13: * 
  14: * @author Marcio Wesley Borges
  15: */
  16:public class MyXMLRenderer extends XMLRenderer {
  17:
  18:    @Override
  19:    public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
  20:        final UIXhtmlComponent xhtmlComponent = (UIXhtmlComponent) uiComponent;
  21:        final ResponseWriter writer = facesContext.getResponseWriter();
  22:        final String tag = xhtmlComponent.getTag();
  23:        writer.startElement(tag, xhtmlComponent);
  24:
25: if ("html".equals(tag)) { 26: writer.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml", null); 27: }
28: 29: final Iterator attributeIterator = xhtmlComponent.getTagAttributes().entrySet().iterator(); 30: while (attributeIterator.hasNext()) { 31: Map.Entry attribute = (Map.Entry) attributeIterator.next(); 32: writer.writeAttribute((String) attribute.getKey(), attribute.getValue(), null); 33: } 34: } 35: 36:} 37:
Also, we need to configure the application to use this render above while Icefaces will be playing with xhtml tags, so just add the following lines at the faces-config.xml file of your web application:
   1:<?xml version='1.0' encoding='UTF-8'?>
   2:<faces-config version="1.2"  xmlns="http://java.sun.com/xml/ns/javaee"
   3:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
   4:    <application>
   5:        <locale-config>
   6:            <default-locale>pt_BR</default-locale>
   7:            <supported-locale>pt_BR</supported-locale>
   8:            <supported-locale>en</supported-locale>
   9:        </locale-config>
  10:        <message-bundle>com.solvoj.sondaletra.web.Bundle</message-bundle>
  11:        <view-handler>com.icesoft.faces.facelets.D2DFaceletViewHandler</view-handler>
  12:    </application>
13: <render-kit> 14: <render-kit-id>ICEfacesRenderKit</render-kit-id> 15: <render-kit-class>com.icesoft.faces.renderkit.D2DRenderKit</render-kit-class> 16: <renderer> 17: <component-family>com.icesoft.faces.XhtmlComponent</component-family> 18: <renderer-type>com.icesoft.domXhtml</renderer-type> 19: <renderer-class>com.solvoj.sondaletra.faces.MyXMLRenderer</renderer-class> 20: </renderer> 21: <renderer> 22: <component-family>com.icesoft.faces.XhtmlComponent</component-family> 23: <renderer-type>com.icesoft.faces.Xhtml</renderer-type> 24: <renderer-class>com.solvoj.sondaletra.faces.MyXMLRenderer</renderer-class> 25: </renderer> 26: </render-kit>
It's enough to produce the resultant html page that I expect:
   1:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   2:<html id="document:html" lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
   3:<head>
The same principe can be used to add or change any attribute that you need to any xhtml tag using Icefaces/Facelets.

Labels: , , , , , ,

2009/04/04

woodstock.xhr.post: Do you see Google? See?!

How to post a JSON data via woodstock.xhr.post?

Woodstock Festival

Sometimes simple things may be hard to do... but I'm one of 'the last Woodstock survives
- No, I wasn't at Woodstock Festival - but, I wanted to.

I learned the Woodstock JSF Components (now officially abandoned by Sun) and I'm using it in at least two projects. Damn! I love Dojo! And Woodstock was all built with Dojo. But, now, after a long time learning (reading, trying, testing, experiencing and going mad), after finally to know what and how to do with Woodstock, the project was buried. I'm desolated!

I did a good work using Woodstock, but now I should migrate to Icefaces (acording Sun), but I don't want and I can't rewrite all my work to another technology.

Several troubles I had using Woodstock and nearly ten times, several troubles I solved with it.

AJAX using Woodstock

When I need to use AJAX with Woodstock pages, I don't use Dynafaces. Instead, I used submit or refresh standard Woodstock component feature to do a postback or I use AJAX request with servlet.

To do a AJAX request using the methdo GET is easy and well documented by Woodstock. Bellow, see example showing how to get customer data via AJAX using only the first and last customer names:

   1:function getCustomerByNames(lastName, firstName) {
   2:    var props = {
   3:        async: true,
   4:
   5:        onError: function(xhr) {
   6:            window.alert("An error occurs while sending an AJAX request. See: " + xhr)
   7:        },
   8:
   9:        onReady: function(xhr) {
  10:            var resp = eval('(' + xhr.responseText + ')');
  11:            window.alert("Customer is " + resp.name + " <" + resp.email + ">");  
  12:        },
  13:
  14:        url: "/AjaxBridge?a=Customer&t=getCustomerByCode"
  15:    };
  16:
  17:    props.url += "&lastName=" + lastName;
  18:    props.url += "&firstName=" + firstName;
  19:
  20:    woodstock.xhr.get(props);
  21:}
  22:

From the server-side, each AJAX "Agent" is a subclass of:

   1:package br.com.trilha21.web.store.ajax;
   2:
   3:import java.io.IOException;
   4:import java.io.PrintWriter; 
   5:import java.lang.reflect.Method;
   6:import java.util.logging.Level;
   7:import java.util.logging.Logger;
   8:import javax.servlet.ServletException;
   9:import javax.servlet.http.HttpServletRequest;
  10:import javax.servlet.http.HttpServletResponse;
  11:import net.marciowb.poison.web.jsf.JSFUtil;
  12:import org.json.JSONException;
  13:import org.json.JSONObject;
  14:
  15:/**
  16: *
  17: * @author Marcio Wesley Borges
  18: */
  19:public class AjaxAgent {
  20:    private static final Logger logger = Logger.getLogger(AjaxAgent.class.getName());
  21:    
  22:    final String task;  
  23:    protected final HttpServletRequest request;
  24:    protected final HttpServletResponse response;
  25:    protected final JSONObject mainObj;
  26:    
  27:    protected AjaxAgent(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  28:        this.request = request;
  29:        this.response = response;
  30:        response.setBufferSize(16384);
  31:        task = getParam("t");
  32:        try {
  33:            mainObj = new JSONObject();        
  34:            mainObj.put("agent", getClass().getSimpleName());
  35:            mainObj.put("by", task);
  36:        } catch (JSONException ex) {
  37:            throw new ServletException(ex);
  38:        }
  39:    }
  40:    
  41:    public String getTask() {
  42:        return task;
  43:    }
  44:    
  45:    protected static JSONObject toJSONObject(Object bean) {
  46:        try {
  47:            return JSFUtil.buildJSONObject(bean);
  48:        } catch (Exception ex) {
  49:            logger.log(Level.SEVERE, null, ex);
  50:        }
  51:        return null;
  52:    }
  53:    
  54:    private void outputJson() throws IOException, JSONException {
  55:        response.setContentType("text/json;charset=UTF-8");
  56:        response.setHeader("Cache-Control", "no-cache");        
  57:        final PrintWriter writer = response.getWriter();
  58:        writer.print(mainObj.toString());
  59:        writer.close();
  60:    } 
  61:    
  62:    protected String getParam(String name) {
  63:        return request.getParameter(name);
  64:    }
  65:
  66:    protected Long getParamAsLong(String name) {
  67:        final String p = getParam(name);
  68:        return Long.valueOf(p);
  69:    }
  70:
  71:    public final void exec() throws ServletException, IOException {
  72:        try {
  73:            final Method m = getClass().getMethod(task);
  74:            
  75:            m.invoke(this);
  76:            outputJson();
  77:        } catch (NoSuchMethodException ex) {
  78:            response.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED );
  79:        } catch (Exception ex) {
  80:            logger.log(Level.SEVERE, "Error while executing an AJAX request.", ex);
  81:            response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.toString() );
  82:        }
  83:    }
  84:
  85:}
  86:

The servlet to attend AJAX request is like:

   1:package br.com.trilha21.web.store.ajax;
   2:
   3:import java.io.IOException;
   4:import java.lang.reflect.Constructor;
   5:import java.util.Map;
   6:import java.util.WeakHashMap;
   7:import java.util.logging.Level;
   8:import java.util.logging.Logger;
   9:import javax.servlet.ServletException;
  10:import javax.servlet.http.HttpServlet;
  11:import javax.servlet.http.HttpServletRequest;
  12:import javax.servlet.http.HttpServletResponse;
  13:
  14:/**
  15: * @author Marcio Wesley Borges
  16: */
  17:public class AjaxBridgeServlet extends HttpServlet {
  18:    private static final Logger logger = Logger.getLogger(AjaxBridgeServlet.class.getName());
  19:    
  20:    private static final String PCKG = AjaxBridgeServlet.class.getPackage().getName() + ".agents.";
  21:    private static final Map<String, Class<? extends AjaxAgent>> agents = new WeakHashMap<String, Class<? extends AjaxAgent>>();
  22:
  23:    private static final String AGENT_NAME_SUFIX = "Agent";
  24:   
  25:    private <T extends AjaxAgent> Class<T> getAgent(String agentName) {
  26:        if (!agentName.endsWith(AGENT_NAME_SUFIX))
  27:            agentName+=AGENT_NAME_SUFIX;
  28:
  29:        Class<T> agentClass = (Class<T>)agents.get(agentName);
  30:        if (agentClass==null) {
  31:            try {
  32:                agentClass = (Class<T>) Class.forName( PCKG + agentName );
  33:            } catch (ClassNotFoundException ex) {
  34:                return null;
  35:            }
  36:            agents.put(agentName, agentClass);
  37:        }
  38:        return agentClass;
  39:    }
  40:    
  41:    /** 
  42:    * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
  43:    * @param request servlet request
  44:    * @param response servlet response
  45:    */
  46:    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  47:    throws ServletException, IOException {
  48:        try {
  49://        response.setContentType("text/html;charset=UTF-8");
  50:            final String agentName = request.getParameter("a");
  51:            final Class<? extends AjaxAgent> agentClass = getAgent(agentName);
  52:            if (agentClass == null) {
  53:                response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
  54:                return;
  55:            }
  56:
  57:            final Constructor agentConstructor = agentClass.getConstructors()[0];
  58:            final AjaxAgent agent = (AjaxAgent)agentConstructor.newInstance(request, response);
  59:            agent.exec();
  60:            return;
  61:            
  62:        } catch (Throwable ex) {
  63:            logger.log(Level.SEVERE, "Error in AjaxBridgeServlet while processing the request: " + request, ex);
  64:        }
  65:        
  66:        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  67:    } 
  68:
  69:    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
  70:    /** 
  71:    * Handles the HTTP <code>GET</code> method.
  72:    * @param request servlet request
  73:    * @param response servlet response
  74:    */
  75:    protected void doGet(HttpServletRequest request, HttpServletResponse response)
  76:    throws ServletException, IOException {
  77:        processRequest(request, response);
  78:    } 
  79:
  80:    /** 
  81:    * Handles the HTTP <code>POST</code> method.
  82:    * @param request servlet request
  83:    * @param response servlet response
  84:    */
  85:    protected void doPost(HttpServletRequest request, HttpServletResponse response)
  86:    throws ServletException, IOException {
  87:        processRequest(request, response);
  88:    }
  89:
  90:    /** 
  91:    * Returns a short description of the servlet.
  92:    */
  93:    public String getServletInfo() {
  94:        return "Short description";
  95:    }// </editor-fold>
  96:
  97:}
  98:

And, finally, the implementantion of the AJAX Agent (who is attending the AJAX requests) is like:

   1:package br.com.trilha21.web.store.ajax.agents;
   2:
   3:import br.com.trilha21.web.store.ajax.AjaxAgent;
   4:import br.com.trilha21.web.store.dao.Customer;
   5:import br.com.trilha21.web.store.ejb.CustomerLocal;
   6:import java.io.IOException;
   7:import javax.servlet.ServletException;
   8:import javax.servlet.http.HttpServletRequest;
   9:import javax.servlet.http.HttpServletResponse;
  10:import net.marciowb.poison.ejb.EJBUtil;
  11:import org.json.JSONException;
  12:
  13:/** 
  14: * @author Marcio Wesley Borges
  15: */
  16:public final class CustomerAgent extends AjaxAgent {
  17:    
  18:    final CustomerLocal customerBean = EJBUtil.lookupLocalBean(CustomerLocal.class);
  19:    
  20:    public CustomerAgent(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  21:        super(request,response);
  22:    }
  23:    
  24:    public void getCustomerByDoc() throws ServletException, IOException, JSONException {
  25:        final String customerDoc = getParam("customerDoc");
  26:        
  27:        final Customer customer = customerBean.get(customerDoc);
  28:        mainObj.put("customer", toJSONObject(customer));
  29:    }
  30:    
  31:    public void getCustomerByNames() throws ServletException, IOException, JSONException {
  32:        final String last = getParam("lastName");
  33:        final String first = getParam("firstName");
  34:        
  35:        final Customer customer = customerBean.getCustomerByNames(last,first);
  36:        mainObj.put("customer", toJSONObject(customer));
  37:    }
  38:}
  39:

The code above, works to HTTP requests (via GET method), but it doesn't works to post data (via POST method). To post data using woodstock.xhr, you must use woodstock.xhr.post instead of woodstock.xhr.get

Posting: woodstock.xhr.post

After quickly googling for "woodstock.xhr.post", I cried, 'cause nothing was returned! So, how to post (and recover) data via "woodstock.xhr.post" stuff?

Seeing the woodstock JS documentation, you will find the mention to the parameter content. All post data must be 'posted' via this parameter. So, the idea to pass complex data (as objects with several kinds of properties) is to encode the data in client side and decode in server side. As example, you can pass a object using JSON and decoding it using Java JSON library at server side.

Bellow you see (Object.toJSON is a Prototype utility method) the equivalent post data of the previous client side code supplied:

   1:function getCustomerByNames(lastName, firstName) {
   2:    var props = {
   3:        async: true,
   4:
   5:        onError: function(xhr) {
   6:            window.alert("An error occurs while sending an AJAX request. See: " + xhr)
   7:        },
   8:
   9:        onReady: function(xhr) {
  10:            var resp = eval('(' + xhr.responseText + ')');
  11:            window.alert("Customer is " + resp.name + " <" + resp.email + ">");  
  12:        },
  13:
  14:        url: "/AjaxBridge?a=Customer&t=getCustomerByCode",
15: content: Object.toJSON({ 16: 'lastName': lastName, 17: 'firstName': firstName 18: })
19: }; 20: 21: woodstock.xhr.post(props); 22:} 23:

To read the content parameter passed above in the servlet, you can do:

   1:public final class CustomerAgent extends AjaxAgent {
   2:    
   3:    final CustomerLocal customerBean = EJBUtil.lookupLocalBean(CustomerLocal.class);
   4:    
   5:    public CustomerAgent(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   6:        super(request,response);
   7:    }
   8:    
   9:    public void getCustomerByDoc() throws ServletException, IOException, JSONException {
  10:        final String customerDoc = getParam("customerDoc");
  11:        
  12:        final Customer customer = customerBean.get(customerDoc);
  13:        mainObj.put("customer", toJSONObject(customer));
  14:    }
  15:
16: public void getCustomerByNames() throws ServletException, IOException, JSONException { 17: final String data = IOUtil.readText(request.getInputStream());//Reads the 'content' parameter - it's equivalent to the post body. 18: final JSONObject json = new JSONObject(data); 19: final String lastName = json.getString("lastName"); 20: final String firstName = json.getString("firstName"); 21: final Customer customer = customerBean.getCustomerByNames(lastName,firstName); 22: mainObj.put("customer", toJSONObject(customer)); 23: }
24:} 25:

Good Icefaces look! I'll still with Woodstock for now.

Labels: , , ,