Java equivalent of PHP foreach ($array as $key=>$val)

As a follow up to my previous post, where I complained that there was no easy way in Java to deliver PHP’s foreach ($array as $key=>$val) functionality I have an update. Using Java’s HashMap or LinkedHashMap types, the same result can be achieved. The difference between the two is that LinkedHashMap retains the order of the array.

import java.util.*;
class Foo
{
    public static void main(String[] args)
    {
        Map<String, String> stateMap = new LinkedHashMap<String, String>();
        stateMap.put("ALABAMA", "AL");
        stateMap.put("ALASKA", "AK");
        // ...
        stateMap.put("WYOMING", "WY");
        for (Map.Entry<String, String> state : 
                stateMap.entrySet()) {
                    System.out.printf("The abbreviation for" + state.getKey() 
                + " is " + state.getValue() + "\n");
        }
    }
}

This utilises a HashMap which enables a key value pair to be defined and thereby replicates PHP’s foreach ($array as $key=>$val) functionality.

(sourced via stackoverflow.com)

Using Java application to access web application

I’ve been working a bit with needing to utilise a web service built in PHP from a Java application (it would be easier to just run a full-screen browser, but other constraints remove this option). What this has necessitated is scripting the Java app so that it makes calls to the web app’s API and then parses and utilises the data correctly.

Other than the writing of variations to the existing web app, so that function calls etc are accessed externally and correctly, the main functionality of the Java app has needed to be built into standard function calls which take in parameters and then parse them to dynamically create the correct URL to be called. Essentially the generalised function takes the parameters given and creates a URL which specifies the function required as well as necessary input data for the web app. Unfortunately, Java doesn’t have a nice foreach array iterator that can reference both the key and the value; like PHPs foreach($array as $key=>$val)):

public string makeURL(string baseURL, string pageName, string[][] params) {
    string queryURL = baseURL + "/" + pageName + "?";
    for(int i=0; i<params.length(); i++) {
	string param = params[i][0] + "=" + params[i][1] + "&";
	queryURL += param;
    }
    queryURL = queryURL.subString(0, queryURL.length() - 1);
    return queryURL;
} 

Next we use a function call to wrap up all the creation of a URL, requesting it, and receiving the response:

public string callURL(string queryURL) { 
    URLConnection queryConn = queryURL.openConnection();
    BufferedReader in = new BufferedReader(
            new InputStreamReader(
	    queryConn.getInputStream()));
    String inputLine;
    String result = ""; 
    while ((inputLine = in.readLine()) != null) {
	result += inputLine;
    }
    in.close();
    return result;
}

The second general function is given the returned data from the URL request and parses it into variables for use by the Java app; the data returned is structured as a 2-D array with the equivalent of a key and value held in the 2nd dimension:

public string[] extractData(string response, string[] nodeNames = null) { 
    string[] data = new Array();
    string[] tokens = StringUtils.splitspanserveAllTokens(response, ":");
    for(int i=0; i<tokens.length(); i++) {
	string[] step = StringUtils.splitspanserveAllTokens(tokens[i], "$");
	data[i][0] = step[0];
	data[i][1] = step[1];
    } 	
    return data; 
} 

Of course, my extractData function is extremely simplistic and only splits a string up. Parsing XML is a better solution if the URL returns XML formatted data. This would require either explicit foreknowledge of the exact nodes being returned by a request (I have allowed for this with the string[] nodeNames) or a much bigger function to allow for searching through and detecting all node names and then dynamically iterating them.

I’m sure there are cleaner, and better, implementations of this, however I felt the need to build my own since I’m dabbling back into Java at present. And once it’s built, I believe it’s best to share. Hopefully this helps someone, let me know.

quick update – me now

Another tutorial up earlier, and I’m starting to get this code plug-in working for Live Writer. Colours/colors are there, it’s just a bit of adjusting to go. No one really supports PHP properly for the plug-ins I can find.

Working on setting up a Java/cURL version of my PHP app at the moment, as the implementation will apparently be better on the hardware as an app, not a browser based set-up.

Job hunt’s still going, applied for a few more today. A couple of promising leads there, so we’ll see what the new week brings.

A few more tuts to polish up too, so more of tat over the weekend when I get a chance.

PHP script to spread text over multiple pages

Sometimes you’ll get a text file that is way too big to reasonably display all on one web page, this script is a simple paginator, which spreads the text over multiple pages cleanly. For the purposes of this demo, I have the data being read from a text file, however a more scalable approach would be to have the data being read from a database (I have commented this into the script).

<?php
function currPageName() {
	return substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], 
"/")+1);
}
$filename = "text.txt";
$this_page = currPageName();
if(isset($_REQUEST['step'])) $step = $_REQUEST['step'];
if(isset($_REQUEST['start'])) $start = $_REQUEST['start'];
if(isset($_REQUEST['file'])) $filename = $_REQUEST['file'];
// **************************************************
// or cut this out and allow the database script
// **************************************************
if(!strstr(".txt", $filename)) { $file = $filename; $filename .= ".txt"; }
else $file = substr($filename, 0, strlen($filename)-4);
$text = "";
if(file_exists($filename)) {
	$file_handle = fopen($filename, "rb");
	while (!feof($file_handle) ) {
		$text .= fgets($file_handle);
	}
	fclose($file_handle);
}
// **************************************************
// cut to here when allowing the database script
// **************************************************
/*
$file = $filename;
require("./db_connector.php"); // your database connection file
$sql = "SELECT * FROM your_table_name WHERE file={$filename} LIMIT 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
mysql_close($conn); // assuming your connector is called $conn
$heading = $row['heading'];
$text = $row['data'];
*/
$text_limit = 600;
$text_array = explode(" ", $text);
$text_total_words = count($text_array);
if(!isset($step)) {
	$start = 0;
	$step = $text_limit;
}
$text_display = $text; 
if($text_total_words > $text_limit) { // if the page needs to be split up
	$text_display = ""; 
	for($x = $start; $x < $step; $x++) {
		$text_display .= $text_array[$x]." ";
	}
	$text_display = str_replace("\n\n", "\n</p>\n<p>\n", $text_display);
	if($start > 0) { // not page one
		$pstart = $start - $text_limit;
		if($pstart < 0) $pstart = 0;
		$pstep = $pstart + $text_limit;
		$text_display = "<a class=\"backforward\" href=\"{$this_page}?
file={$file}&start={$pstart}&step={$pstep}\"><&nbsp;Prev page</a></p>\n<br />
<br /><br />\n<p>{$text_display}";
	}
	if($text_total_words > $step) { // not the end of the text
		$nstart = $start + $text_limit;
		$nstep = $step + $text_limit;
		if($nstep > $text_total_words) $nstep = $text_total_words;
		$text_display = "{$text_display}</p>\n<br /><br /><br />\n<p>
<a class=\"backforward\" href=\"{$this_page}?file={$file}&start={$nstart}&
step={$nstep}\">Next page&nbsp;></a>";
	}
}
else { $text_display = str_replace("\n\n", "\n</p>\n<p>\n", $text_display); }
?>
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html lang="en" xml:lang="en">
<head>
	<title>page_stepper</title>
	<meta http-equiv="Content-Type" content="txt/html; charset=utf-8" />
	<style type="text/css">
* {
	margin: 0;
	padding: 0;
}
html {
	background: #ddd;
}
body {
	margin: 1em 10%;
	padding: 1em 3em;
	font: 80%/1.4 tahoma, arial, helvetica, lucida sans, sans-serif;
	border: 1px solid #999;
	background: #eee;
	position: relative;
}
a {
	color: #024378;
	font-weight: bold;
	text-decoration: none;
}
a:hover {
	color: #04569A;
	text-decoration: underline;
}
.backforward, .backforward:visited {
	background: #222 url(./site_images/overlay.png) repeat-x; 
	display: inline-block; 
	padding: 5px 10px 6px; 
	color: #fff; 
	text-decoration: none;
	-moz-border-radius: 6px; 
	-webkit-border-radius: 6px;
	-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.6);
	-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.6);
	text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
	border: none;
	border-bottom: 1px solid rgba(0,0,0,0.25);
	position: relative;
	cursor: pointer;
	font-size: 13px; 
	font-weight: bold; 
	line-height: 1; 
	text-shadow: 0 -1px 1px rgba(0,0,0,0.25); 
	background-color: #e62727; 
}
.backforward:hover { background-color: #cf2525; }
</style>
    
</head>
<body>
<?php echo "<p>\n{$text_display}\n</p>"; ?>
</body>
</html>

I’ve hacked in a bit of CSS from the WampServer CSS to make it look pretty, but the buttons are mine. Basically the script pulls out the desired number of words from the text data, and prints it. If there are preceeding words, a “previous” button is prepended to the text; if there is more to come, a “next” button is appended.

PHP function to randomize a file name

I made the function for a web project I was working on, but then didn’t end up using it. All it does is take the given file name, check the file-type and then create a random string as the new file name while keeping the file-type intact. If there is no file-type (ie the file name given is just the name, the function will just return a random string as a new file name

function randomizeFileName( $real_file_name ) {     
        $name_parts = @explode( ".", $real_file_name );     
        $ext = "";     
        if ( count( $name_parts ) > 0 ) {         
                $ext = "." . $name_parts[count( $name_parts ) - 1];     
        }     
        return substr(md5(uniqid(rand(),1)), -16) .$ext;
}

Not much more to say about it really.

function to format text file to HTML with PHP

This function takes in a text document, and reformats it for use on an HTML page.

function processText($text) {       
        $text = str_replace("&gt;", ">", $text);       
        $text = str_replace("&lt;", "<", $text);       
        $text = str_replace("\r\n\r\n", "\n", $text);       
        $text = str_replace("\r\n", "\n", $text);       
        $text = str_replace("\n\n", "\n", $text);       
        $text = str_replace("\n", " </p>\n<p> ", $text);       
        $text = "<p>".$text."</p>";       
        return $text;
}

Line by line, the process is:

Step 1

$text = str_replace("&gt;", ">", $text) and $text = str_replace("&lt;", "<", $text) – here each occurrence of “>” or “<” is replaced by it’s corresponding ASCII value (&gt; or &lt;).

Step 2

$text = str_replace("\r\n\r\n", "\n", $text) – here we replace “\r\n\r\n” double line breaks with a single “\n” line break (this is not HTML yet, but we will deal with this soon)

Step 3

$text = str_replace("\r\n", "\n", $text) – here we replace “\r\n” single line breaks with a single “\n” line break (again, this is not HTML yet, but we will deal with this)

Step 4

$text = str_replace("\n\n", "\n", $text) – here we replace “\n\n” double line breaks with a single “\n” line break (this is not HTML yet, but we are about to deal with this)

Step 5

$text = str_replace("\n", " </p>\n<p> ", $text) – here we replace “\n” single line breaks with a “</p>\n<p>” HTML paragraph break. As all other breaks have been converted to “\n” prior to this, they all become paragraphs

Step 6

$text = "<p>".$text."</p>" – this final line makes sure the text begins and ends with HTML paragraph tags.

automatically add soft hyphens to long words with PHP

Soft hyphens are optional hyphens that HTML will use when required to wrap a word to make sure it does not breach the space provided. This is a PHP function to add soft hyphens into words where required, and take the muscle word out of the equation.

function addSoftHyphen($word, $maxLen) {     
        if(strpos($word, "&shy;") === false) {         
                if(strlen($word) > $maxLen) {             
                        $word = substr($word, 0, $maxLen)."&shy;"
.substr($word, $maxLen);             
                        if(strlen(substr($word, strrpos($word, "&shy;")+5))
>$maxLen) {                 
                                $word = addSoftHyphen($word, $maxLen);             
                        }         
                }     
        }     
        else {         
                if(strlen(substr($word, strrpos($word, "&shy;")+5))>$maxLen) {             
                        $word = substr($word, 0, strrpos($word, "&shy;")+5
+$maxLen)."&shy;".substr($word, strrpos($word, "&shy;")+5+$maxLen);         
                }         
                if(strlen(substr($word, strrpos($word, "&shy;")+5))>$maxLen) {             
                        $word = addSoftHyphen($word, $maxLen);         
                }     
        }     
        return $word;
}

Just replace each occurrence of the excessively long word in question with a call to addSoftHyphen($word, $maxLen) and the word will be carefully broken and hyphenated as and when required without you needing to check each occurrence.