Currently Browsing: Tutorials

Why email clients block sender images

This is a feature of email clients that all of you out there must have stumbled on. Emails sent with images embedded in them (not as attachments but in the body of the message) often appear as blocked from your email client (outlook, thunderbird, yahoo mail, hotmail, gmail etc). This happens for several reasons. The root of the cause is because when an image is embedded in a message, your email client is required to open an external source and retrieve some data. In an ideal world these data would be just an harmless image. Nowadays though this is not the case.

One thing that an image source in an email can be is some sort of trojan horse that will be set to execute once you try to view the so called image. If you are unprotected by an antivirus then you will most probably be in a big trouble. This is rarely the case though simply because email clients these days are thin programs (with no way of executing code on your machine) or even web applications.

The most widely used practice of images in messages is from spammers. Now, one would ask why would a spammer do it. The mechanism is simple. Here it is step by step:

  1. Some friend of yours forwarded a message of the type “if you don’t forward this ……..” to you and a few other zillion people.
  2. The forward chain keeps on going accumulating addresses in the form of “original message from blah blah to blah blah”.
  3. This message makes it’s way back to the spammer that started this whole story, sometimes years after. Note: You don’t believe the years after part? Do you remember that email about mars being bigger than ever and all that crap? Take a peek here.
  4. The spammer now has your email in his database and you start getting all those “buy viagra now from a cheap Canadian pharmacy” and all that nonsense.
  5. Now, in that email there is an image with a source originating on a link like this “http://iamalamespammer.com/images/viagra.jpg?verify=klsjdfh994“.
  6. When you open that email and retrieve that image you basically verified to the spammer that the email that landed on his hands is correct and checked!

See what the spammer did is pretty simple. His link as you can see has a path to an image and then a parameter “verify=klsjdfh994″. He associates that parameter with your email address and issues a different one for each email he sends out. So once the specific parameter is sent to the server of the spammer he knows that this particular email (and email address consequently) is valid and reached a target!

As you can see email clients have a very good reason for blocking images from emails. Now you, as a user, I would suggest to keep that restriction and lift it only conditionally and to senders that you know.

The (X)HTML strict way to open a new window

There has been a fuss on websites that don’t go through validation simply because they have a wrong way of opening a link on a new window. The old conventional way of opening a link on a new window was simply by adding an attribute like:

  1. <a href="http://example.com" target="_blank">My new window link</a>

This was both easy to remember and implement. Since the 4.0 strict specification though this is not considered valid any more. I was against that until I read the reason why this changed. Simply because the meta information an HTML document contains is related to the current window and current site. Should you want to refer to a new window it’s simply not within the scope of this page’s description. That’s why it is considered to fall within the client side to implement through Javascript for example.

I am not sure I agree with that since it doesn’t really interfere with the meaning of the meta description of the page that the current HTML does, it’s simply an easy way to do it. On the other hand, since you want the validation to be successful, the easiest way to do it is by adding a small Javascript on the link. You can do it like:

  1. <a onclick="window.open(this.href); return false;" href="http://example.com">My new window link</a>

It’s not as hard but it’s definitely not as simply as the first way. What do you prefer? Simplicity or validity? It’s really up to you but I usually go with the first…

Using Windows Sharepoint Services (WSS) to create a new site

To cut to the chase, the process of creating a new subsite using WSS is as follows:

  1. Connect to the main site using SPSite.
  2. Add the new site using the Add() method on AllWebs collection.
  3. Do all kinds of magic using the newly created site.

Here is a small C# code example:

  1. SPSite rootSite = new SPSite("http://testsite");
  2. SPWeb site = rootSite.AllWebs.Add("testsub");

In order to access this site you need to visit “http://testsite/testsub”. Hope this helps!

Hook up C# with Windows Sharepoint Services (WSS) tutorial

In this small tutorial i shall demonstrate how to hook up C# to use the Windows Sharepoint Services API (WSS). It’s fairly simple and straightforward. You need the following:

  1. A machine running Windows server 2003/08 with Sharepoint installed.
  2. Microsoft Visual Studio 2005.
  3. About 15 minutes.

For the purposes of this example, we will create a small console application that will list all the sites of a Sharepoint site. First of open Visual Studio and create a new Visual C# console application. Next step is adding the reference to the WSS API on our project. To do so, you can go on the explorer window, right click on the “References” and click “Add Reference…”. On the window that will show up choose “Windows Sharepoint Services” dll from the .NET packages.

Once this step is done, off to the code:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Microsoft.SharePoint;
  5.  
  6. namespace TestApp
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             SPSite root = new SPSite("http://testsite");//this is the URL to the sharepoint site we want to connect to
  13.             foreach (SPWeb site in root.AllWebs)//looping through the collection of the sites
  14.             {
  15.                 Console.WriteLine(site.Name);
  16.             }
  17.             Console.ReadLine();
  18.         }
  19.     }
  20. }

From here on, sky is the limit! You can view a documentation of the WSS API here.

How to use bindings in the backing beans in ADF 10g

This is a follow up to the original post about acquiring a bindings object in backing beans in ADF. Some have had the question, how to use the bindings for standard operations in the backing beans. Hence this post!

The answer is – easy. As soon as you’ve got the bindings (oracle.binding.BindingContainer object) instance, you can do a lot of interesting stuff with it.

Always keep in mind, that it represents the page definition, meaning that it “contains” whatever the pageDef does.

Create a class like the following one:

  1. import oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding;
  2. import javax.faces.application.FacesMessage;
  3. import javax.faces.context.FacesContext;
  4. import javax.faces.el.ValueBinding;
  5. import oracle.adf.model.binding.DCBindingContainer;
  6. import oracle.binding.BindingContainer;
  7. import oracle.jbo.Transaction;
  8. import oracle.jbo.domain.Number;
  9. import oracle.jbo.server.ApplicationModuleImpl;
  10. import oracle.jbo.uicli.binding.JUIteratorBinding;
  11.  
  12. public class ADFUtils {
  13.  
  14. private BindingContainer bindings; //this is mainly used to store bindings, but in fact its just an implementation of java.util.Map
  15. private DCBindingContainer dcBindings; //whilst this class gives much more control over the bindings
  16. private FacesContext ctx;
  17. private static Utils instance;
  18. private Transaction transaction;
  19.  
  20. public ADFUtils(BindingContainer bindings) {
  21. this.bindings = bindings;
  22. this.ctx = FacesContext.getCurrentInstance();
  23. ValueBinding vb = this.ctx.getApplication().createValueBinding("#{bindings}");
  24. this.dcBindings = (DCBindingContainer) vb.getValue(this.ctx);
  25. this.transaction = dcBindings.getDataControl().getApplicationModule().getTransaction();
  26. }
  27.  
  28. public Object resolveExpresssion(String expression) {
  29. Object obj = this.bindings.get(expression);
  30. return obj;
  31. }
  32.  
  33. public JUIteratorBinding resolveIterator(String iterName) {
  34. JUIteratorBinding iter = (JUIteratorBinding)this.getBindings().get(iterName);
  35. return iter;
  36. }
  37.  
  38. public FacesCtrlActionBinding resolveAction(String actionName) {
  39. FacesCtrlActionBinding action = (FacesCtrlActionBinding) this.getBindings().get(actionName);
  40. return action;
  41. }
  42.  
  43. public void resolveActionAndExecute(String actionName) {
  44. FacesCtrlActionBinding action = resolveAction(actionName);
  45. action.execute();
  46. }
  47.  
  48. public JUIteratorBinding executeActionAndGetIterator(String actionName) {
  49. FacesCtrlActionBinding action = resolveAction(actionName);
  50. action.execute();
  51. JUIteratorBinding iter = action.getIteratorBinding();
  52. return iter;
  53. }
  54.  
  55. /*
  56. * This affects only the application module the bindings object belongs to.
  57. */
  58. public void globalCommit() throws Exception {
  59. if (transaction.isDirty()) {
  60. transaction.commit();
  61. System.out.println("Changes have been committed");
  62. }
  63. else {
  64. System.err.println("No unmodified data to commit");
  65. }
  66. }
  67.  
  68. /*
  69. * This affects only the application module the bindings object belongs to.
  70. */
  71. public void globalRollback() {
  72. if (transaction.isDirty()) { //and transaction has modified data
  73. transaction.rollback();
  74. System.out.println("Changes have been rollbacked");
  75. }
  76. else {
  77. System.err.println("No unmodified data to rollback");
  78. }
  79. }
  80.  
  81. //MESSAGES
  82.  
  83. public boolean hasErrors() {
  84. FacesMessage.Severity maxSeverity = this.ctx.getMaximumSeverity();
  85. return (maxSeverity != null? maxSeverity.compareTo(FacesMessage.SEVERITY_ERROR) == 0 || maxSeverity.compareTo(FacesMessage.SEVERITY_FATAL) == 0 : false);
  86. }
  87.  
  88. public void inform(String messageText) {
  89. FacesMessage message = new FacesMessage(messageText);
  90. message.setSeverity(FacesMessage.SEVERITY_INFO);
  91. this.ctx.addMessage(null, message);
  92. }
  93.  
  94. public void setBindings(BindingContainer bindings) {
  95. this.bindings = bindings;
  96. }
  97.  
  98. public BindingContainer getBindings() {
  99. return bindings;
  100. }
  101.  
  102. public Transaction getTransaction() {
  103. return transaction;
  104. }
  105.  
  106. public DCBindingContainer getDcBindings() {
  107. return dcBindings;
  108. }
  109.  
  110. public ApplicationModuleImpl getAppModuleImpl(String dataControlName){
  111. javax.faces.context.FacesContext ctx = javax.faces.context.FacesContext.getCurrentInstance();
  112. javax.faces.el.ValueBinding bind = ctx.getApplication().createValueBinding("#{data}");
  113. oracle.adf.model.BindingContext bindingContext = (oracle.adf.model.BindingContext) bind.getValue(ctx); //resolve binding context
  114. oracle.adf.model.binding.DCDataControl dataControl = bindingContext.findDataControl(dataControlName);//find data control by name (defined in DataBindings.cpx) from BindingContext
  115. /*
  116. * finally get the View Object instance which the iterator is bound to (see the attribute Binds in the iterator definition in the pageDef)
  117. * then invoke the magic method executeEmptyRowSet on it
  118. */
  119. return (ApplicationModuleImpl) dataControl.getDataProvider();
  120. }
  121.  
  122. }

So now all you have to do is instantiate the ADFUtil class and invoke its methods!

« Previous Entries