<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:www.refactormycode.com,2007:users87</id>
  <link type="application/atom+xml" href="http://www.refactormycode.com/users/87" rel="self"/>
  <title>Marco Valtas</title>
  <updated>Wed Aug 25 19:58:27 -0700 2010</updated>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor527508</id>
    <published>2010-08-25T19:58:27-07:00</published>
    <title>[Java] On Access HashMap key by value</title>
    <content type="html">&lt;p&gt;You're looking for a bidirectional map, check &lt;a href="http://code.google.com/p/guava-libraries/" target="_blank"&gt;http://code.google.com/p/guava-libraries/&lt;/a&gt;  look for BiMap class.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/1418-access-hashmap-key-by-value/refactors/527508" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor309117</id>
    <published>2009-09-17T02:17:22-07:00</published>
    <title>[PHP] On MD5 strings</title>
    <content type="html">&lt;p&gt;Maybe you should post this code here &lt;a href="http://thedailywtf.com/Series/CodeSOD.aspx" target="_blank"&gt;http://thedailywtf.com/Series/CodeSOD.aspx&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/1035-md5-strings/refactors/309117" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor250743</id>
    <published>2009-08-12T03:10:09-07:00</published>
    <title>[Java] On replace with regex</title>
    <content type="html">&lt;p&gt;Here's my example, use a simple backreference (&lt;a href="http://www.regular-expressions.info/java.html" target="_blank"&gt;http://www.regular-expressions.info/java.html&lt;/a&gt;) to capture the portion of the path you are interested, after that you substitute the &amp;quot;\&amp;quot; for &amp;quot;.&amp;quot; &lt;/p&gt;

&lt;pre&gt;## RegexpExample [java]
public class RegExpExample {
	public static void main(String[] args) {

		System.out.println(
				
                  &amp;quot;c:\\dev\\svnlocal\\project\\target\\classes\\com\\company\\project\\File.class&amp;quot;
                 .replaceAll(&amp;quot;.*classes\\\\(.*).class$&amp;quot;,&amp;quot;$1&amp;quot;).replaceAll(&amp;quot;\\\\&amp;quot; , &amp;quot;.&amp;quot;)
		
		);
		
	}
}
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/990-replace-with-regex/refactors/250743" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor151373</id>
    <published>2009-03-17T13:40:38-07:00</published>
    <title>[Java] On First LotusScript Agent</title>
    <content type="html">&lt;p&gt;This code isn&#194;&#180;t Java.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/789-first-lotusscript-agent/refactors/151373" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor146252</id>
    <published>2009-02-08T01:01:59-08:00</published>
    <title>[Bash] On sort | uniq alternative</title>
    <content type="html">&lt;p&gt;Hi, this problem remembered me of my time in Bioinformatics. Usually we had problems like yours to solve, but instead of 2000 lines, the files had much more lines and performance was always a concern. I couldn't not get if you want to sort the file or not. When using a tool like uniq you probably will have to sort the file before remove any duplicates.&lt;/p&gt;

&lt;p&gt;My solution is not in 'bash' since in bioinformatics we use a lot of Perl, and you mentioned tools like bash and awk I have a good guess that we can access a little of Perl to solve your problem. I will assume too, that you don't want to sort the file just remove duplicates, as you will see, you could sort just adding a couple of lines in the solution.&lt;/p&gt;

&lt;p&gt;Hope this helps.
&lt;/p&gt;

&lt;pre&gt;## comments [plain_text]

# here's some steps.
# headers.dmp is a file with proteins headers, here's a sample:

[mavcunha@strongcoffee tmp]$ head headers.dmp 
&amp;gt;Q4U9M9|104K_THEAN 104 kDa microneme/rhoptry antigen precursor - Theileria annulata
&amp;gt;P15711|104K_THEPA 104 kDa microneme/rhoptry antigen precursor - Theileria parva
&amp;gt;Q43495|108_SOLLC Protein 108 precursor - Solanum lycopersicum (Tomato) (Lycopersicon esculentum)
&amp;gt;P18646|10KD_VIGUN 10 kDa protein precursor - Vigna unguiculata (Cowpea)
&amp;gt;P13813|110KD_PLAKN 110 kDa antigen - Plasmodium knowlesi
&amp;gt;Q9XHP0|11S2_SESIN 11S globulin seed storage protein 2 precursor - Sesamum indicum (Oriental sesame) (Gingelly)
&amp;gt;P19084|11S3_HELAN 11S globulin seed storage protein G3 precursor - Helianthus annuus (Common sunflower)
&amp;gt;P13744|11SB_CUCMA 11S globulin subunit beta precursor [Contains: 11S globulin gamma chain - Cucurbita maxima (Pumpkin) (Winter squash)
&amp;gt;P32234|128UP_DROME GTP-binding protein 128up - Drosophila melanogaster (Fruit fly)
&amp;gt;P21215|12AH_CLOS4 12-alpha-hydroxysteroid dehydrogenase - Clostridium sp. (strain C 48-50)

# The original file has 389046 lines.
[mavcunha@strongcoffee tmp]$ wc -l headers.dmp 
  389046 headers.dmp

# and these lines are uniq.
[mavcunha@strongcoffee tmp]$ cat headers.dmp | sort | uniq  | wc -l 
  389046

# I created a little script (code omited) to mess with the file and create some duplicated lines.
[mavcunha@strongcoffee tmp]$ perl create_dups.pl headers.dmp &amp;gt; headers_dup.dmp 

# and the new file has more lines..
[mavcunha@strongcoffee tmp]$ wc -l headers_dup.dmp 
  502917 headers_dup.dmp

# here is the code to remove duplicated lines in perl, it's a simple algorithm:
# 
# read the line,
# check if the line exists in a associative array.
# if exists go to the next line.
# if not, put on the associative array and print the line.

## [perl]
#!/usr/bin/perl

open(F, shift) or die($!);
while(&amp;lt;F&amp;gt;) {
    next if exists($lines{$_});
    $lines{$_}++;
    print $_;
}
close F;

## comments2 [plain_text]

# to run just pass the filename and redirect to output.
[mavcunha@strongcoffee tmp]$ perl remove_dup.pl headers_dup.dmp &amp;gt; headers_clean.dmp

# now let's check if this file is really clean
# first let's count the lines

[mavcunha@strongcoffee tmp]$ wc -l headers_clean.dmp 
  389046 headers_clean.dmp

# seems the same, what about a diff with the original?
[mavcunha@strongcoffee tmp]$ diff headers.dmp headers_clean.dmp 
[mavcunha@strongcoffee tmp]$ 

# I think we done it.
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/739-sort-uniq-alternative/refactors/146252" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor145126</id>
    <published>2009-01-31T02:00:10-08:00</published>
    <title>[Java] On PSiGate</title>
    <content type="html">&lt;p&gt;Here's some Java way to think about. Probably you can get some library to deal with your structure, but in this example I coded myself. When you deal with OO programing, specially Java, you should use objects to map your domain instead of Strings &amp;quot;here&amp;quot; and &amp;quot;there&amp;quot;, this will force a more strongly typed code and less errors. &lt;/p&gt;

&lt;p&gt;I coded some classes to represent your file (domain) and a simple exporter, this architecture allows other exporters and you can control what data is valid in each option of your XML. &lt;/p&gt;

&lt;p&gt;Lastly, using some interfaces and polymorphism the exporter can be very flexible.&lt;/p&gt;

&lt;p&gt;Hope this Helps.
&lt;br /&gt; &lt;/p&gt;

&lt;pre&gt;package psigate.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Order {
	
	private Map&amp;lt;String,String&amp;gt; orderInfo = new HashMap&amp;lt;String, String&amp;gt;();
	private List&amp;lt;Item&amp;gt; items = new ArrayList&amp;lt;Item&amp;gt;();
	
	public void addInfo(String info, String value) {
		this.orderInfo.put(info, value);
	}
	public void addItem(Item item) {
		this.items.add(item);
	}
	public Map&amp;lt;String, String&amp;gt; getInfo() {
		return this.orderInfo;
	}
	public List&amp;lt;Item&amp;gt; getItems() {
		return this.items;
	}
}


package psigate.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Item {
	
	private Map&amp;lt;String, String&amp;gt; itemInfo = new HashMap&amp;lt;String, String&amp;gt;();
	private List&amp;lt;ItemOption&amp;gt; itemOptions = new ArrayList&amp;lt;ItemOption&amp;gt;();
	
	public void addOption(ItemOption opt) {
		this.itemOptions.add(opt);
	}
	public void addInfo(String info, String value) {
		this.itemInfo.put(info, value);
	}
	public Map&amp;lt;String, String&amp;gt; getInfo() {
		return this.itemInfo;
	}
	public List&amp;lt;ItemOption&amp;gt; getOptions() {
		return this.itemOptions;
	}
}


package psigate.model;

import java.util.HashMap;
import java.util.Map;

public class ItemOption {

	private Map&amp;lt;String, String&amp;gt; itemOptions = new HashMap&amp;lt;String, String&amp;gt;();
	
	public void addOption(String optionName, String value) {
		itemOptions.put(optionName, value);
	}
	public Map&amp;lt;String, String&amp;gt; getOptions() {
		return this.itemOptions;
	}
}


package psigate.export;

import java.util.Map;

import psigate.model.Item;
import psigate.model.ItemOption;
import psigate.model.Order;

public class OrderExporter {

	public static String toXML(Order o) {
		StringBuffer sb = new StringBuffer();
		sb.append(&amp;quot;&amp;lt;Order&amp;gt;\r\n&amp;quot;);
		
		sb.append(putBetweenTags(o.getInfo()));
		
		for(Item i : o.getItems()) {
			sb.append(&amp;quot;&amp;lt;Item&amp;gt;\r\n&amp;quot;);
			sb.append(putBetweenTags(i.getInfo()));
			
			sb.append(&amp;quot;&amp;lt;Option&amp;gt;\r\n&amp;quot;);
			for(ItemOption io : i.getOptions()) {
				sb.append(putBetweenTags(io.getOptions()));
			}
			sb.append(&amp;quot;&amp;lt;/Option&amp;gt;\r\n&amp;quot;);
			
			sb.append(&amp;quot;&amp;lt;/Item&amp;gt;\r\n&amp;quot;);
		}
		
		sb.append(&amp;quot;&amp;lt;/Order&amp;gt;\r\n&amp;quot;);
		
		return sb.toString();
	}
	
	private static String putBetweenTags(String tagName, String value) {
		return &amp;quot;&amp;lt;&amp;quot;+ tagName + &amp;quot;&amp;gt;&amp;quot; + value + &amp;quot;&amp;lt;/&amp;quot; + tagName + &amp;quot;&amp;gt;\r\n&amp;quot;;
	}
	
	private static String putBetweenTags(Map&amp;lt;String, String&amp;gt; map) {
		StringBuffer sb = new StringBuffer();
		for(String key : map.keySet()) {
			sb.append(putBetweenTags(key, map.get(key)));
		}
		return sb.toString();
	}
}


import psigate.export.OrderExporter;
import psigate.model.Item;
import psigate.model.ItemOption;
import psigate.model.Order;


public class OrderTest {

	public static void main(String[] args) {
		Order o = new Order();
		o.addInfo(&amp;quot;Passphrase&amp;quot;, &amp;quot;passtest&amp;quot;);
		o.addInfo(&amp;quot;UserID&amp;quot;, &amp;quot;someuser&amp;quot;);
		
		Item i = new Item();
		i.addInfo(&amp;quot;ItemID&amp;quot;, &amp;quot;book&amp;quot;);
		i.addInfo(&amp;quot;ItemDescription&amp;quot;, &amp;quot;good book&amp;quot;);
		
		ItemOption io = new ItemOption();
		
		io.addOption(&amp;quot;Size&amp;quot;, &amp;quot;2&amp;quot;);
		
		i.addOption(io);
		
		o.addItem(i);
		
		Item i2 = new Item();
		i2.addInfo(&amp;quot;ItemID&amp;quot;, &amp;quot;book&amp;quot;);
		i2.addInfo(&amp;quot;ItemDescription&amp;quot;, &amp;quot;another book&amp;quot;);
		
		ItemOption io2 = new ItemOption();
		
		io2.addOption(&amp;quot;Size&amp;quot;, &amp;quot;2&amp;quot;);
		
		i2.addOption(io2);
		
		o.addItem(i2);
		
		System.out.println(OrderExporter.toXML(o));
	}
}
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/727-psigate/refactors/145126" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor55119</id>
    <published>2008-10-14T22:35:48-07:00</published>
    <title>[Perl] On Delete files from a directory</title>
    <content type="html">&lt;p&gt;Hi, usually I use File::Find for a recusive removal of files, it&#194;&#180;s simple and fast (example bellow). For the problem you stated I quote the perldoc of readdir function:&lt;/p&gt;

&lt;p&gt;&amp;quot;If you're planning to filetest the return values out of a readdir, you'd better prepend the directory in question. Otherwise, because we didn't chdir there, it would have been testing the wrong file.&amp;quot;&lt;/p&gt;

&lt;p&gt;So if you check the doc there&#194;&#180;s a example similar to yours, using File::Spec is not dirty, is portable! But you can, as the perldoc mention, just chdir to remove the files.&lt;/p&gt;

&lt;p&gt;Hope this helps.
&lt;/p&gt;

&lt;pre&gt;## [perl]

#!perl

sub purge_archive {
    my $dir = shift;

    die(&amp;quot;$dir is not a directory!\n&amp;quot;) unless -d $dir;

    opendir(DIR, $dir) || die &amp;quot;Can't opendir $dir: $!&amp;quot;;

       chdir($dir) or die &amp;quot;Can&#194;&#180;t change to dir $dir: $!&amp;quot;;

        @files = grep { !/^\./ &amp;amp;&amp;amp; -f } readdir(DIR);

        unlink @files;

    closedir DIR;
}

sub purge_archive_recursive {
    my $dir = shift;

    die(&amp;quot;$dir is not a directory!\n&amp;quot;) unless -d $dir;

    find(
        sub {
            unlink unless /^\./ or -d;
        },
        $dir
    );
}&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/532-delete-files-from-a-directory/refactors/55119" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor14897</id>
    <published>2008-08-12T19:02:19-07:00</published>
    <title>[PHP] On Array and ForEach Loop</title>
    <content type="html">&lt;p&gt;My experience tells that I should avoid create or parse XML files &amp;quot;manually&amp;quot; every time I can. XMLs files can get very complicated and parsing/creating XMLs can be a nightmare. &lt;/p&gt;

&lt;p&gt;Well, in PHP I use for cases like this the SimpleXML library (&lt;a href="http://www.php.net/manual/en/book.simplexml.php" target="_blank"&gt;http://www.php.net/manual/en/book.simplexml.php&lt;/a&gt;) which usually is already compiled with your PHP dist. For one example similar to your code look at &lt;a href="http://www.php.net/manual/en/function.simplexml-element-addChild.php" target="_blank"&gt;http://www.php.net/manual/en/function.simplexml-element-addChild.php&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As for the array above, you could use a simple foreach($array as $key =&amp;gt; $value), the example is bellow.&lt;/p&gt;

&lt;pre&gt;## refact [php]

&amp;lt;?php

$payload = array(
    'email'       =&amp;gt; 'test@test.com',
    'lastName'    =&amp;gt; 'test',
    'firstName'   =&amp;gt; 'test',
    'passwd'      =&amp;gt; 'password',
    'phone'       =&amp;gt; 'test',
    'company'     =&amp;gt; 'test',
    'companySize' =&amp;gt; 'test',
    'teamSize'    =&amp;gt; 'test',
    'country'     =&amp;gt; 'USA',
    'p'           =&amp;gt; 'test');

foreach($payload as $key =&amp;gt; $value) {
	echo &amp;quot;$key =&amp;gt; $value\n&amp;quot;;
}

?&amp;gt;
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/430-array-and-foreach-loop/refactors/14897" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor14657</id>
    <published>2008-08-08T17:31:30-07:00</published>
    <title>[PHP] On Getter and Setter</title>
    <content type="html">&lt;p&gt;The concept of a getter/setter is just to avoid access to the attributes of your class directly. So you provide methods for access instead of exposing the inners of your class, a example is:&lt;/p&gt;

&lt;p&gt;The class Foo has a attribute *age*, if you expose the attribute anyone could just set &amp;lt;age&amp;gt; directly (as your code above), worst, they could set to a invalid age like -10. &lt;/p&gt;

&lt;p&gt;Another problem with your code is that you are mixing $_GET[] with the construction of your class, this is not the right way to do it. A simple new Foo() will have a lot of side effects and your class isn&#194;&#180;t portable nor secure. Anyone could pass any value to your class just teaking the URL.&lt;/p&gt;

&lt;p&gt;If you have a class and want construct it, the parsing of URL paremeters should live outside the class (or a class exclusive for this task), access $_GET and $_POST inside the attendant script (the one invoked by the server) instead of mixing your class with handling the server request. To be more clear, if you want reuse this class in a non web environment you can&#194;&#180;t because you mixed the class with the environment where it resides.&lt;/p&gt;

&lt;p&gt;In the example bellow your handling script is the script which is the target for a URL (&lt;a href="http://server/your_script.php" target="_blank"&gt;http://server/your_script.php&lt;/a&gt;), there you take care of any evil parameter, the class have a validation but in this case is more like a integrity check. In Java this happens more naturally because Java is strong typed, but in PHP you have to check the types by yourself. PHP can use type hinting but just for array() or a class.&lt;/p&gt;

&lt;p&gt;The points are, getters/setters are for your class integrity and valid state, do not receive URL parameters inside the construction or anywhere inside your class unless you designed the class just to do the task of receiving parameters and etc. Usually in PHP you should double check the parameters received.&lt;/p&gt;

&lt;p&gt;Hope this helps. 
&lt;/p&gt;

&lt;pre&gt;## Foo [php]

&amp;lt;?php

class Foo {
 
  private $age;

  public function set_age($p_age) {
     if($p_age &amp;gt;= 0) $this-&amp;gt;age = $p_age;
  }

}

?&amp;gt;

## handling [php]
&amp;lt;?php
// simple validation...
if(IsSet($_GET['age'])) {

   // this should be a integer value, forcing type coercion.
   $req_age = intval($_GET['age']);
   
    // after a type coercion, the parameter is still the same size?
    if(strlen($req_age) === strlen($_GET['age'])) {
       $foo_ojb = new Foo();
       $foo_ojb-&amp;gt;set_age($req_age); // the class should accept only a valid age.
    }

}
?&amp;gt;
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/425-getter-and-setter/refactors/14657" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor14223</id>
    <published>2008-07-31T19:06:24-07:00</published>
    <title>[Java] On Closing database connections properly</title>
    <content type="html">&lt;p&gt;Hi, you should probably use a singleton pattern (&lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern" target="_blank"&gt;http://en.wikipedia.org/wiki/Singleton_pattern&lt;/a&gt;) on your DatabaseBean to get the context and connection only once for each run, if you application get a connection in one class, then passes the result to another which gets connection too you&#194;&#180;re probably consuming more resources then you need.&lt;/p&gt;

&lt;p&gt;Way back in time, before Hibernate, the CementJ&#194;&#180;s DatabaseUtility (&lt;a href="http://tinyurl.com/6jqgxn" target="_blank"&gt;http://tinyurl.com/6jqgxn&lt;/a&gt;) was a good choice to close result sets and connections, still I have in some projects. &lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/409-clsing-database-connections-properly/refactors/14223" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor14168</id>
    <published>2008-07-31T03:24:01-07:00</published>
    <title>[Bash] On Memory usage script</title>
    <content type="html">&lt;p&gt;I think is a very good script, solves your problem and will be solely maintained by you. I have a handful of this kind of script in my ~/bin directory. But there's somethings I probably change. First is the reuse of you format string, you can make it less redundant just putting in a variable. Second, I don't fell comfortable mixing  too much languages so, as a exercise, I tried to do this all in Perl. The problem was that I have a mac and could not paste the code here so you can use on your Linux without some tweaks here and there. If have some time you can look at the Perl module &amp;quot;Proc::ProcessTable&amp;quot; (&lt;a href="http://is.gd/19PZ" target="_blank"&gt;http://is.gd/19PZ&lt;/a&gt;) which can provide a OO way to access this kind of information, this way you can expand your script more easily. 
&lt;br /&gt;The third thing is that you can use VAR=`which perl` if you have all programs in your path and don't worry where they are in the system.&lt;/p&gt;

&lt;p&gt;The thing is, your script is very good for some reasons I wrote before, I personally wouldn't bother to more flexible if not necessary. If you pick yourself adding more processes and for each one more redundancy then is time to fix.&lt;/p&gt;

&lt;p&gt;Hope this helps. &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/407-memory-usage-script/refactors/14168" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor14025</id>
    <published>2008-07-29T13:51:19-07:00</published>
    <title>[PHP] On Object with Field names as resources</title>
    <content type="html">&lt;p&gt;I did something similar not long ago. I needed one ORM in PHP but Doctrine (&lt;a href="http://www.phpdoctrine.org/" target="_blank"&gt;http://www.phpdoctrine.org/&lt;/a&gt;) was not a option  because I had some restriction on my env. So I went and wrote some very light ORM.&lt;/p&gt;

&lt;p&gt;The idea is similar with yours, since is kind a big code I will try to show the basic.&lt;/p&gt;

&lt;p&gt;I have some classes AbstractTable, AbstractEntry, TableFactory and DBTypeMapper. I think is pretty straight forward their functions. The first catch is that TableFactory scans a subdir looking for a table definition, this because a table definition mention primary keys but not the columns. &lt;/p&gt;

&lt;p&gt;TableFactory gives you a object if your table type, since this object is a AbstractTable, mostly operations in a table is centrilized in this class. If I get one query that is too specific for a table I just implement the method inside the table definition file. &lt;/p&gt;

&lt;p&gt;I will paste a simple method of AbstractTable, find() which searchs for a entry based on table primary keys. Note that this method returns a object of type entry, so each table has his own class and each entry has too.&lt;/p&gt;

&lt;p&gt;One final consideration is type mapping, I wanted to pass a object of type 'entry' to find similar entries and etc. So I wrote a simple type mapper based on Oracle&#194;&#180;s types. In AbstractTable code look at method find_by_entry(), it receives one abstract entry and searchs the database for it, but since PHP isn&#194;&#180;t strogly typed I had to figure out what type is the column before create the 'where' clause. &lt;/p&gt;

&lt;p&gt;The catch with DBTypeMapper is that it fetches the meta information from Oracle when given a table name and use defined handlers for each type. &lt;/p&gt;

&lt;p&gt;All works well for a lightweight ORM, I wouldn&#194;&#180;t bet this kind of structure for a really big framework, not without some revisions. In the and I will paste what a sample of a code using this structure to be more clear.&lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;## TableFactory [php]
&amp;lt;?php

class TableFactory {

  public static function getTable($tableName) {

    $tableName = ucfirst(strtolower($tableName));

    if(include_once('tables/'.$tableName.'.php')) {
      return new $tableName;
    }
    else {
      throw new Exception('tabela '.$tableName.' n&#195;&#163;o definida no diret&#195;&#179;rio &amp;quot;tables/&amp;quot; ');
    }
  }
}
?&amp;gt;

## A table definition [php]
&amp;lt;?php
// table manip...
class Basic_login extends AbstractTable {

  protected $primary_key = 'LOGIN_ID';

}

class Basic_login_entry extends AbstractEntry { }

?&amp;gt;

## AbstractTable [php]

&amp;lt;?php

  public function find($id) {
    return $this-&amp;gt;find_by($this-&amp;gt;primary_key,$id);
  }

  public function find_by($column, $value) {

    $select = 'SELECT * FROM '.strtoupper(get_class($this)).
      ' WHERE '.strtoupper($column).' = '.$value;

    $stmt = $this-&amp;gt;ocihelper-&amp;gt;parse($select);

    $this-&amp;gt;ocihelper-&amp;gt;execute($stmt);

    return $this-&amp;gt;_map_result($stmt);
  }

 protected function _map_result($stmt) {
    $entries = array();

    while($row = oci_fetch_assoc($stmt)) {

      // class represents a entry in table
      $entryClass = get_class($this); $entryClass .='_entry';
      $entry = new $entryClass;

      // map columns found to fields...
      foreach($row as $field =&amp;gt; $value) {
        $property = strtolower($field);
        if(!oci_field_is_null($stmt,$field)) {
          $entry-&amp;gt;$property = $value;
        }
      }
      $entries[] = $entry;
    }

    // return all entries found
    return $entries;
  }

  public function find_by_entry(AbstractEntry $entry) {

    $this-&amp;gt;is_entry_eq_class($entry);

    $this-&amp;gt;dbtypemapper-&amp;gt;map($entry);

    $sql = &amp;quot;SELECT * FROM &amp;quot;.strtoupper(get_class($this)). &amp;quot; WHERE &amp;quot;;

    $terms;
    foreach($entry-&amp;gt;get_fields() as $field) {
      $terms[] = strtoupper($field).'='.$entry-&amp;gt;$field;
    }
    
    $sql .= implode(' AND ',$terms);

    $stmt = $this-&amp;gt;ocihelper-&amp;gt;parse($sql);

    $this-&amp;gt;ocihelper-&amp;gt;execute($stmt);

    return $this-&amp;gt;_map_result($stmt);
  }
?&amp;gt;

## DBTypeMapper [php]

&amp;lt;?php

class DBTypeMapper {

  private $conn;

  public function __construct() {
    $this-&amp;gt;conn = DBConnection::get()-&amp;gt;handle();
  }

  public function map(AbstractEntry $entry) {

    // get the table name from entry object.
    $table_name = strtoupper(str_replace('_entry', '', get_class($entry)));

    if(!IsSet($this-&amp;gt;cache[$table_name])) $this-&amp;gt;load_table_schema($table_name);

    // calling handlers for each type found
    foreach($this-&amp;gt;cache[$table_name] as $column =&amp;gt; $type) {
      $property = strtolower($column);
      if(IsSet($this-&amp;gt;handlers[$type]) &amp;amp;&amp;amp; IsSet($entry-&amp;gt;$property)) {
        $entry-&amp;gt;$property = $this-&amp;gt;handlers[$type]-&amp;gt;map($entry-&amp;gt;$property);
      }
    }
  }

  private function load_table_schema($table_name) {

    $table_name = strtoupper($table_name); // oracle uses upper case.

    $sql = &amp;quot;
      SELECT COLUMN_NAME, DATA_TYPE 
      FROM USER_TAB_COLUMNS
      WHERE TABLE_NAME='$table_name'&amp;quot;;

    $stmt = oci_parse($this-&amp;gt;conn,$sql);

    if (!$stmt) {
      $e = oci_error($this-&amp;gt;conn);
      throw new Exception($e['message']);
    }

    $r = oci_execute($stmt, OCI_DEFAULT);

    if (!$r) {
      $e = oci_error($stmt);
      throw new Exception($e['message']);
    }

    while($row = oci_fetch_array($stmt)) {
      $this-&amp;gt;cache[$table_name][$row['COLUMN_NAME']] = $row['DATA_TYPE'];
      $datatypes[$row['DATA_TYPE']] = true;
    }

    // load handlers for types found
    foreach(array_keys($datatypes) as $type) {
      $class_name = 'Map_'.$type;
      if(!IsSet($this-&amp;gt;handlers[$type])) {
        if(class_exists($class_name)) {
          $this-&amp;gt;handlers[$type] = new $class_name();
        }
        else {
          $this-&amp;gt;handlers[$type] = new Map_GENERIC();
        }
      }
    }
  }

}

// Type mappers. Estas classes formatam os dados
// corretamente para o banco de dados conforme o esquema
// exportado pela tabela em user_tab_columns no ORACLE.
// Ex. uma data do tipo 10/02/2008 ser&#195;&#161; formatada pelo 
// mapper Map_DATE para to_date('10/02/2008' 'dd/mm/yyyy')
interface TypeMapper {
  static function map($field);
  //static function unmap($field);
}

class Map_GENERIC implements TypeMapper {
  public static function map($field) {
    return $field;
  }
}

class Map_DATE extends Map_GENERIC implements TypeMapper {
  public static function map($field) {
    if($field == '') return;

    if(preg_match('/^(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})$/', $field, $m)) {
      return &amp;quot;TO_DATE('$m[1]','dd/mm/yyyy hh24:mi:ss')&amp;quot;;
    }
    elseif(preg_match('/^(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2})$/', $field, $m)) {
      return &amp;quot;TO_DATE('$m[1]','dd/mm/yyyy hh24:mi')&amp;quot;;
    }
    elseif(preg_match('/^(\d{2}\/\d{2}\/\d{4} \d{2})$/', $field, $m)) {
      return &amp;quot;TO_DATE('$m[1]','dd/mm/yyyy hh24')&amp;quot;;
    }
    elseif(preg_match('/^(\d{2}\/\d{2}\/\d{4})$/', $field, $m)) {
      return &amp;quot;TO_DATE('$m[1]','dd/mm/yyyy')&amp;quot;;
    }
    elseif(preg_match('/^(\d{2}\/\d{2}\/\d{2})$/', $field, $m)) {
      return &amp;quot;TO_DATE('$m[1]','dd/mm/yy')&amp;quot;;
    }
    elseif(preg_match('/^(\d{10})$/', $field, $m)) { // epoch time
      return &amp;quot;(TO_DATE('19700101','YYYYMMDD')+ $field/86400)&amp;quot;;
    }
    else {
      throw new Exception(&amp;quot;Don&#194;&#180;t know how to convert ($field) to date for ORACLE.&amp;quot;);
    }
  }
}

class Map_VARCHAR2 extends Map_GENERIC implements TypeMapper {
  public static function map($field) {
    $field = preg_replace(&amp;quot;/'/&amp;quot;,&amp;quot;\'&amp;quot;,$field); // escape '
    return &amp;quot;'$field'&amp;quot;;
  }
}

?&amp;gt;

## Sample of a insert [php]

&amp;lt;?php

// $config_date, $serial_number and etc were previous given...

$t_conf   = TableFactory::getTable('single_conf');

$new_config_id = $t_conf-&amp;gt;next_seq_value();

$new_entry = $t_conf-&amp;gt;new_entry();

$new_entry-&amp;gt;config_id                 = $new_config_id;
$new_entry-&amp;gt;date                      = $config_date;
$new_entry-&amp;gt;enable                    = 1;
$new_entry-&amp;gt;serialnumber              = $serial_number;
$new_entry-&amp;gt;username                  = $username;
$new_entry-&amp;gt;source                    = $source;

$t_conf-&amp;gt;insert($new_entry);


?&amp;gt;

&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/400-object-with-field-names-as-resources/refactors/14025" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor13443</id>
    <published>2008-07-21T05:59:01-07:00</published>
    <title>[Perl] On MAC Formatting</title>
    <content type="html">&lt;p&gt;I think there's a million ways to this, I think a simple call will keep the code smaller. The trick here is, first the 'g' flag turns the match operation a kind a loop, if put it in a while will work too. The join function catches all matches and glue with ':' and the group (?:0x) will take care on avoiding match the prefix '0x'.
&lt;br /&gt;Hope this helps.&lt;/p&gt;

&lt;pre&gt;## refact [perl]
#!/usr/bin/perl
use strict;
use warnings;

# sample snmp return
my $mac_address = '0x001617479a5e';

print qq{Original MAC Address: $mac_address\n};

$mac_address = join(':',($mac_address =~ m/(?:0x)?(\w{2})/g));

print qq{Reformatted MAC Address: $mac_address\n};
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/390-mac-formatting/refactors/13443" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor12056</id>
    <published>2008-06-28T04:13:05-07:00</published>
    <title>[Bash] On kill nginx master proces</title>
    <content type="html">&lt;p&gt;In Linux check the &amp;quot;pkill&amp;quot; command.&lt;/p&gt;

&lt;pre&gt;## [bash]

pkill &amp;quot;nginx: master&amp;quot;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/338-kill-nginx-master-proces/refactors/12056" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor4154</id>
    <published>2008-03-19T16:54:46-07:00</published>
    <title>[Perl] On Hello world!</title>
    <content type="html">&lt;p&gt;A simple one, don&#194;&#180;t know if is more obscure but certainly fun.&lt;/p&gt;

&lt;pre&gt;perl -e &amp;quot;$_='doHole klrWlg';$_.=$1,print$2while s/(..)(.)//;&amp;quot;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/262-hello-world/refactors/4154" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor1741</id>
    <published>2008-01-25T00:30:53-08:00</published>
    <title>[Java] On clean up nested loops?</title>
    <content type="html">&lt;p&gt;I think you can remove the nested loop doing a sort before find the duplicates, then going in one step using a Set data structure to keep the duplicates. &lt;/p&gt;

&lt;p&gt;The gain is that the Set structure will take care of future duplicates and you avoid the double trip in the Array. This assuming you can sort your items.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;## sort before [java]

java.util.Arrays.sort(cArray);

for(int i = 0; i &amp;lt; cArray.length - 1; i++) {
	if(cArray[i].equals(cArray[i + 1])) {
		dupes.add(cArray[i]);
	}
}&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/215-clean-up-nested-loops/refactors/1741" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor817</id>
    <published>2007-11-10T15:01:03-08:00</published>
    <title>[Java] On Incompatible Types</title>
    <content type="html">&lt;p&gt;Hi, here some explanation of what was going on in your code.&lt;/p&gt;

&lt;p&gt;In line 15: 
&lt;br /&gt;When you have a local variable with the same name of a instance variable you should tell the java compiler what is what. In fact is a good practice always refer to instance variables with &amp;quot;this.variableName&amp;quot;.&lt;/p&gt;

&lt;p&gt;In line 38:
&lt;br /&gt;That's is a incompatible type, you begin a String array and try to put one double inside. Remember that your &amp;quot;values&amp;quot; instance variable is of double type, so the &amp;quot;tmp&amp;quot; variable should be a double too.&lt;/p&gt;

&lt;p&gt;In line 40:
&lt;br /&gt;Two problems here, first is that you should return a String not a Range object, remember the your method declaration:
&lt;br /&gt;   public String reverseString()&lt;/p&gt;

&lt;p&gt;The second problem is that you try to construct a Range object with your &amp;quot;tmp&amp;quot; variable (of String[] type before refactoring), but your Range should be constructed only with integers, javac will complain about this too.&lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/147-incompatible-types/refactors/817" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor815</id>
    <published>2007-11-10T02:20:17-08:00</published>
    <title>[Java] On Cannot Ref from Static Content</title>
    <content type="html">&lt;p&gt;Mark,
&lt;br /&gt; I see you are beginning in the Java World, welcome. For this particular issue you can read this short article (&lt;a href="http://www.leepoint.net/notes-java/flow/methods/50static-methods.html" target="_blank"&gt;http://www.leepoint.net/notes-java/flow/methods/50static-methods.html&lt;/a&gt;) about static and non-static methods, this site has a lot information you can use.&lt;/p&gt;

&lt;p&gt; Hope this helps.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/145-cannot-ref-from-static-content/refactors/815" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor738</id>
    <published>2007-11-05T16:09:23-08:00</published>
    <title>[Java] On Equals Method</title>
    <content type="html">&lt;p&gt;Wheres the hashCode() implementation? &lt;/p&gt;

&lt;p&gt;Here is a complete description of what you need to know about equals() and hashCode().&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.geocities.com/technofundo/tech/java/equalhash.html" target="_blank"&gt;http://www.geocities.com/technofundo/tech/java/equalhash.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and here is a old refactoring post about the subject of equals() and hashCode()&lt;/p&gt;

&lt;p&gt;&lt;a href="http://refactormycode.com/codes/27-sample-java-program#refactor_160" target="_blank"&gt;http://refactormycode.com/codes/27-sample-java-program#refactor_160&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this help.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/135-equals-method/refactors/738" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor729</id>
    <published>2007-11-05T11:58:21-08:00</published>
    <title>[Java] On Errors With Exception</title>
    <content type="html">&lt;p&gt;Here is my corrections they are identified in the code. &lt;/p&gt;

&lt;p&gt;You got your contructor argument wrong, the lenght of a array should be tested with a &amp;quot;&amp;lt;&amp;quot; not a &amp;quot;&amp;lt;=&amp;quot; since arrays in java start at zero, but the length have the size. So a array as &amp;quot;new String[10]&amp;quot; will have 10 elements starting at 0 to 9, That was your first ArrayOutOfBoundsException.&lt;/p&gt;

&lt;p&gt;The park() method tested with a &amp;quot;&amp;gt;&amp;quot;, but should be &amp;quot;&amp;lt;&amp;quot; for the same reason as above.&lt;/p&gt;

&lt;p&gt;And finally &amp;quot;numCars&amp;quot; should be incremented with &amp;quot;numCars++&amp;quot;, because integers has a default of &amp;quot;0&amp;quot;, so you want park the car then increment, not increment then park the car.&lt;/p&gt;

&lt;p&gt;Hope this helps.
&lt;/p&gt;

&lt;pre&gt;## Parks [java]

public class Parks {
    private String[] parkingBays;
    private int numCars;

    public Parks(int capacity) {
        parkingBays = new String[capacity]; // changed &amp;quot;numCars&amp;quot; to &amp;quot;capacity&amp;quot;

        for (int i = 0; i &amp;lt; parkingBays.length; i++) { // changed &amp;quot;&amp;lt;=&amp;quot; to &amp;quot;&amp;lt;&amp;quot;
            parkingBays[i] = &amp;quot;Empty&amp;quot;;
        }
    }
    public boolean park(String car) {
        
        if (numCars &amp;lt; parkingBays.length){ // changed &amp;quot;&amp;gt;&amp;quot; to &amp;quot;&amp;lt;&amp;quot;
            parkingBays[numCars++] = car; // changed &amp;quot;++numCars&amp;quot; to &amp;quot;numCars++&amp;quot;
        }
        else {
            return false;
        }
        return true;
    }


    /**
     * For Testing
     */
    public static void main(String [] args) {
        Parks p = new Parks(20);
        boolean spaces = true;
        while (spaces) {
            spaces = p.park(&amp;quot;car1&amp;quot;);
            spaces = p.park(&amp;quot;car2&amp;quot;);
        }
        for (String car : p.parkingBays)
            System.out.println(car);
    }
}&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/134-errors-with-exception/refactors/729" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor644</id>
    <published>2007-10-30T05:20:03-07:00</published>
    <title>[PHP] On Robots Reader</title>
    <content type="html">&lt;p&gt;Hi, when I saw your code I thought that a class Robot could be useful, the nicest thing was that I found a Perl module (WWW::RobotRules) that do exactly what your code propose but in a OO way. &lt;/p&gt;

&lt;p&gt;What I did was translate the Perl module to PHP. You can tweak around to see if help on your problem.  I'm not a professional PHP programmer so maybe some specific optimization can be done.&lt;/p&gt;

&lt;p&gt;Some caveats: the regular expression engine PCRE does not allow repeat quantifiers on lookahead assertions. (see: &lt;a href="http://www.php.net/manual/en/reference.pcre.pattern.syntax.php" target="_blank"&gt;http://www.php.net/manual/en/reference.pcre.pattern.syntax.php&lt;/a&gt;) but in the original Perl module were some, actually one, I don't think will differ but keep it in mind (in the function useragent()). I've could not test this code enough so care should be taken.   &lt;/p&gt;

&lt;p&gt;As you probably will notice I didn't translated all functionality of the original module, there's no time keeping and one object WWW_Robot should e used for only one domain.&lt;/p&gt;

&lt;p&gt;Hope this helps.
&lt;/p&gt;

&lt;pre&gt;## WWW_Robot [php]
&amp;lt;?
class WWW_Robot {

  var $url;
  var $useragent = &amp;quot;*&amp;quot;;

  // array which we mark the disallowed paths
  var $rules = null;

   /* Should find and parse the robots file,
    * cache the result for -&amp;gt;allowed() subsequent calls.
    * If the file could not be found -&amp;gt;allowed() should
    * return TRUE for any call.
    */
  function parseURL($url_given) {

    // boolean flags...
    $is_me   = false;
    $is_anon = false;
    $me_disallowed   = null;
    $anon_disallowed = null;

    $this-&amp;gt;url = parse_url($url_given);

    $robot_file_data = $this-&amp;gt;retrieve_robot_file($this-&amp;gt;url);

    if(! isset($robot_file_data) ) { // robots.txt not exists

    }
    else { // robots.txt file exists

      foreach(explode(&amp;quot;\n&amp;quot;,$robot_file_data) as $line) {

        $line = preg_replace(&amp;quot;/\015$/&amp;quot;, &amp;quot;&amp;quot;, $line); // removing CRs if exists.

        if(preg_match(&amp;quot;/\s*\#/&amp;quot;, $line)) continue; // skipping comments.

        $line = preg_replace(&amp;quot;/\s*\#.*/&amp;quot;, &amp;quot;&amp;quot;, $line); // removing comments at end of a line.

        if(preg_match(&amp;quot;/^\s*$/&amp;quot;, $line)) {
          if($is_me) break;
          $is_anon = false;
        }
        elseif(preg_match(&amp;quot;/^User-Agent:\s*(.*)/i&amp;quot;, $line, $found)) {

          $ua = preg_replace(&amp;quot;/\s+$/&amp;quot;, &amp;quot;&amp;quot;, $found[1]); // removing tralling space.

          if($is_me) {
          }
          elseif( $ua == '*' ) {
            $is_anon = true;
          }
          elseif($this-&amp;gt;match_with_me($ua)) {
            $is_me = true;
          }

        }
        elseif(preg_match(&amp;quot;/^Disallow:\s*(.*)/i&amp;quot;, $line, $found)) {

          if(!isset($ua)) $is_anon = true; // disalow w/o previous UA, assuming *

          $disallow = strtolower(preg_replace(&amp;quot;/\s+$/&amp;quot;, &amp;quot;&amp;quot;, $found[1]));


          if($is_me) {
            $me_disallowed[]   = $disallow;
          }
          elseif($is_anon) {
            $anon_disallowed[] = $disallow;
          }

        }
        else {
          /* Google, and probably others, uses a Allow in robots.txt, this is probably a extenssion
           * of the robots.txt syntax, we do not support these. 
           * If want to to see warnings about these lines uncomment the
           * code below.
           */
          
          //trigger_error(&amp;quot;Strange line in robots file: $line&amp;quot;, E_USER_WARNING);
        }

      }// end foreach()

      if($is_me) {
        $this-&amp;gt;rules = $me_disallowed;
      }
      else {
        $this-&amp;gt;rules = $anon_disallowed;
      }

    }// end else robots.txt file exsits.
  }// end parseURL()

  function match_with_me($ua) {
    if(strtolower($this-&amp;gt;useragent) == strtolower($ua)) {
      return true;
    }
    else {
      return false;
    }
  }

  function retrieve_robot_file($from_url) {

    $robot_file = @file_get_contents($from_url['scheme'].'://'.$from_url['host'].'/robots.txt');

    return $robot_file;
  }


  /*
   * This method returns true if our agent has permission
   * to enter (crawl) the PATH argument. 
   */
  function allowed($path) {

    if(!isset($this-&amp;gt;rules)) return true;

    foreach($this-&amp;gt;rules as $rule) {

      $strcmp_result = strcmp($rule, strtolower($path));

      $pos;

      if($strcmp_result == 0) {
        return false; // we have a match
      }
      elseif($strcmp_result &amp;lt; 0) {
        $pos = strpos($path, $rule, 0);
      }
      else {
        $pos = strpos($rule, $path, 0);
      }

      if($pos === 0) return false;
    }

    return true; // if we could not find a rule to disallow
  }


  // get/set for useragent...
  function useragent($ua = null) {

    if(isset($ua)) {
      $this-&amp;gt;me_disallowed   = null; // cleaning data
      $this-&amp;gt;anon_disallowed = null; // cleaning data
      $this-&amp;gt;useragent = preg_replace(&amp;quot;!/\s*\d+.\d+\s*$!&amp;quot;, &amp;quot;&amp;quot;, $ua); // original re: s!/?\s*\d+.\d+\s*$!!
    }

    return $this-&amp;gt;useragent; // to inform our current useragent.
  }

} //end class
?&amp;gt;


## test code [php]

&amp;lt;?

   // test code...
  $robot = new WWW_Robot;
  $robot-&amp;gt;useragent(&amp;quot;Some UserAgent&amp;quot;);
  $robot-&amp;gt;parseURL(&amp;quot;http://www.google.com.br&amp;quot;);

  // can we crawl this dir in google?
  echo  &amp;quot;-&amp;gt;&amp;quot;.$robot-&amp;gt;allowed(&amp;quot;/defauts/&amp;quot;).&amp;quot;&amp;lt;-\n&amp;quot;;

  // can we crawl this dir in google?
  echo  &amp;quot;-&amp;gt;&amp;quot;.$robot-&amp;gt;allowed(&amp;quot;/trends/&amp;quot;).&amp;quot;&amp;lt;-\n&amp;quot;;

?&amp;gt;
&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/116-robots-reader/refactors/644" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor553</id>
    <published>2007-10-26T13:47:22-07:00</published>
    <title>[Java] On Detect neighboring pixels</title>
    <content type="html">&lt;p&gt;I&#194;&#180;m behind a very nasty firewall/network and I&#194;&#180;ve made a mistake on the above code, missed &amp;quot;thisY + 1&amp;quot; inside the second for. Since I can&#194;&#180;t edit it I will paste here the same code corrected.&lt;/p&gt;

&lt;pre&gt;// See above code, already fixed.&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/110-detect-neighboring-pixels/refactors/553" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor550</id>
    <published>2007-10-26T13:19:26-07:00</published>
    <title>[Java] On Detect neighboring pixels</title>
    <content type="html">&lt;p&gt;Here's a simple way. Note that if you ever want to get the 24 neighbors you just need to use &amp;quot;2&amp;quot; where I&#194;&#180;m using &amp;quot;1&amp;quot; and expand the array.&lt;/p&gt;

&lt;pre&gt;## neighbors [java]

/** 
  * This is a method which will gather the pixels
  * of the 8 pixels surrounding a given pixel
  * @param thisX is the x of the pixel in case
  * @param thisY is the y of the pixel in case
  */
   
  
  public Pixel[] getNeighbors(int thisX, int thisY)
  {
     Pixel[] pixels = new Pixel[8];

     int index = 0;

     for(int i = thisX - 1; i &amp;lt;= thisX + 1; i++) 
     {
       for(int j = thisY - 1; j &amp;lt;= thisY + 1; j++) 
       {
         if(i == thisX &amp;amp;&amp;amp; j == thisY) continue;
           pixels[index] = getPixel(i,j);
           index++;
       }
     }

     return pixels;
  }&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/110-detect-neighboring-pixels/refactors/550" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor525</id>
    <published>2007-10-24T02:45:19-07:00</published>
    <title>[Ruby] On Getting QWERTY misstypes</title>
    <content type="html">&lt;p&gt;Hi, I don't how to write a Ruby solution but you can have some idea looking at this Perl module.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://search.cpan.org/~krburton/String-KeyboardDistance-1.01/KeyboardDistance.pm" target="_blank"&gt;http://search.cpan.org/~krburton/String-KeyboardDistance-1.01/KeyboardDistance.pm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/100-getting-qwerty-misstypes/refactors/525" rel="alternate"/>
  </entry>
  <entry>
    <id>tag:www.refactormycode.com,2007:Refactor443</id>
    <published>2007-10-16T23:31:06-07:00</published>
    <title>[Java] On Email addresses validator</title>
    <content type="html">&lt;p&gt;matrixise, this is more a design choice, theres no performance impact, at least with 15000 emails, in a test a made here. As I don't know if EmailValidator class will have another methods I prefer stay in non-static territory. If you are positive that EmailValidator will be something like a util class( see Effective Java by Joshua Bloch) you can declare isValid() as static.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;</content>
    <author>
      <name>Marco Valtas</name>
      <email>mavcunha@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/73-email-addresses-validator/refactors/443" rel="alternate"/>
  </entry>
</feed>

