JAXB part 4: handling CDATA elements

If you want to specify that element values are CDATA, you can create an adapter class like this:

import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
 * to parse CDATA values.
 * 
 * @author Laura Liparulo
 */
public class AdapterXmlCDATA extends XmlAdapter<String, String> {

    @Override
    public String marshal(String value) throws Exception {
        return "<![CDATA[" + value + "]]>";
    }
    @Override
    public String unmarshal(String value) throws Exception {
        return value;
    }

}

In the bean class, generated by JAXB add the following annotation.

    @XmlJavaTypeAdapter(AdapterXmlCDATA.class)
    protected String description;

In this way any occurrence of the elements with the annotation above will be automatically parsed as CDATA.

JAXB – PART 3 : (un)marshalling xml file with DOCTYPE declaration

Although many XML files have a DOCTYPE declaration, browsing the internet and my safary library account haven´t helped that much to unmarshall (and marshall) my mbeans descriptors with JAXB. It tooks me several hours to find a way out.
Supposing that the xml root element is called “Bean”, you can get the header, simply converting the xml file in a string and taking all the content until the first root element tag (). This might be very useful if you want to scan a folder in which the xml files have different headers (like jboss services configurationes ones).

	public static String getHeader(String filePath) {

		String header = "";
		String xmlContent = "";
		int headerLastIndex = 0;

		File file = new File(filePath);

		String text = "";
		try {
			text = FileUtils.readFileToString(file, "UTF-8");

			headerLastIndex = text.indexOf("<mbean>");
			header = text.substring(0, headerLastIndex);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return header;

	}
	public static void marshaller(Mbean mbean, String filePath, String header)
			throws CustomizerException {

		stringWriter = new StringWriter();

		File file = new File(filePath);
		try {

			jaxbContext = JAXBContext.newInstance(Mbean.class);

			fileWriter = new FileWriter(file);

			marshaller = jaxbContext.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

			marshaller.marshal(mbean, stringWriter);

			System.out.println(stringWriter.toString());

			fileWriter.write(header+stringWriter.toString());

			fileWriter.flush();
			fileWriter.close();

		} catch (MarshalException ex) {

			throw new CustomizerException("Marshalling the file: " + filePath
					+ "not possible. Wrong file content");

		} catch (JAXBException e) {

			throw new CustomizerException("Could not parse the XML file: "
					+ filePath);

		} catch (IOException e) {

			throw new CustomizerException("Couldn´t access the file: "
					+ filePath);
		}

		finally {

			try {
				fileWriter.close();
			} catch (IOException e) {

				throw new CustomizerException(
						"Couldn´t close the fileWriter for: " + filePath);
			}
		}

	}

I would like to make it in a better way with JAXB, but I think that the second version is still a bit raw. Currently there are no unmarshalling properties provided. You can invoke the method setProperty(java.lang.String name, java.lang.Object value), but there are still no properties provided by the API. I would like to contribute to the project…

JAXB – TEAM EXAMPLE – PART 1: XSD schema with root attribute and child element with attribute and value

In this post I will show you how to represent an XSD schema with root attribute and child element with attribute and value. For example, let´s consider a software development team:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<team category="software development">
    <Member role="junior">Laura</Member>
    <Member role="senior">Erik</Member>
    <Member role="graduate">Mike</Member>
</team>

The xsd schema generally represent a a working team :

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://acme.com/schema/type/team/v1" xmlns:team="http://acme.com/schema/type/team/v1"
	xmlns:company="http://acme.com/schema/type/company/v1"
	elementFormDefault="qualified">

	<xsd:element name="Team" type="team:Team" />

	<xsd:complexType name="Team">
		<xsd:annotation>
			<xsd:documentation>Represents a working team </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence maxOccurs="unbounded">
			<xsd:element name="Member">
				<xsd:complexType>
					<xsd:simpleContent>
						<xsd:extension base="xsd:string">
							<xsd:attribute name="role" type="xsd:string" />
						</xsd:extension>
					</xsd:simpleContent>
				</xsd:complexType>
			</xsd:element>
		</xsd:sequence>
		<xsd:attribute name="category" type="xsd:string" />
	</xsd:complexType>
</xsd:schema>

Although it seems to be a typical case, I have spent several hours reading books, tutorials and forum, trying to map a web service xml file with such a structure.
I have finally found the solution on a google forums post.

A better solution would be using the type attribute and make a separate “complexType” tag, because in this way JAXB would be able to create a different bean class for each element (also the nested ones). So an equivalent version of the schema is the following:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://acme.com/schema/type/team/v1" xmlns:team="http://acme.com/schema/type/team/v1"
	xmlns:company="http://acme.com/schema/type/company/v1"
	elementFormDefault="qualified">

	<xsd:element name="Team" type="team:Team" />

	<xsd:complexType name="Team">
		<xsd:annotation>
			<xsd:documentation>Represents a working team </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence>
			<xsd:element name="Member" type="team:member" minOccurs="0"
				maxOccurs="unbounded" />
		</xsd:sequence>
		<xsd:attribute name="category" type="xsd:string" />
	</xsd:complexType>
	
	<xsd:complexType name="member">
		<xsd:simpleContent>
			<xsd:extension base="xsd:string">
				<xsd:attribute name="role" type="xsd:string" />
			</xsd:extension>
		</xsd:simpleContent>
	</xsd:complexType>

</xsd:schema>

In eclipse, downloading the “m2e conntector for jaxb” plugin, you can automatically generate all the object classes from your XSD schema (in the menu bar menu you can find the JAXB section under File>New>…). Without a binding file, you will have to add the “@XmlRootElement” annotation on the top of your root element class and also delete the namespace in the package-info class. I will tell you more in the next posts…

Interface as reference data type in Java

So far, I hadn´t understood that interfaces can be used as data types in java. I discovered it while learning depency injection.
An interface in java is a valid referenca data type. If you want to use an interface as reference variabile, make sure your class implements it!

Here is the interface for any liquid container:

public interface LiquidContainer {

void fill(int ml);
void empty();
void wash();
void drink();

}

The class Glass implements the developed interfaced:

import static java.lang.System.out;

public class Glass implements LiquidContainer{

	@Override
	public void fill(int ml) {
		out.println("Glass filled with "+ml+"!");
	}

	@Override
	public void empty() {
		out.println("Your glass is now empty.");
	}

	@Override
	public void wash() {
		out.println("the glass has been washed.");
	}

	@Override
	public void drink() {
		out.println("you have drunk from a Glass.");
	}
}

Mug is another class implementing the interface:

import static java.lang.System.out;

public class Mug implements LiquidContainer {

	@Override
	public void fill(int ml) {
		out.println("Mug filled with "+ml+"!");
	}

	@Override
	public void empty() {
		out.println("Your Mug is now empty");
	}

	@Override
	public void wash() {
		out.println("Your mug has been washed.");
	}

	@Override
	public void drink() {
        out.println("You have drunk from a mug.");
	}
}

Then we can define two classes: Superman and Batman mugs extending Mug, without specifying what they implement:

import static java.lang.System.out;

public class SupermanMug extends Mug{

	LiquidContainer liquidContainer;

	@Override
	public void fill(int ml) {
		out.println("Superman Mug filled with "+ml+"!");
	}

	@Override
	public void empty() {
		out.println("superman Mug is now empty.");
	}

	@Override
	public void wash() {
		out.println("Superman Mug has been washed.");
	}

	@Override
	public void drink() {
		out.println("you have drunk from a Superman Mug!");
	}
}

And finally a Breakfast class:

public class Breakfast {

LiquidContainer lc;

	static void drinkFromObject(LiquidContainer lc){
		lc.drink();
	}

	public static void main(String args[]){

		SupermanMug sm=new SupermanMug();
		BatmanMug bm=new BatmanMug();
		Glass glass=new Glass();
		Mug mug=new Mug();

		drinkFromObject(glass);
		drinkFromObject(mug);
		drinkFromObject(sm);
		drinkFromObject(bm);
	}
}

The “drinkFromObject” methods work for any liquid container objects, no matter what the class inheritance is, because it takes an interface (LiquidContainer) as reference data type parameter. The resulte is:

you have drunk from a Glass.
You have drunk from a mug.
you have drunk from a Superman Mug!
you have drunk from a Batman Mug!

Subtle, isn´t it?

Jquery paginator for Liferay 6.1

This tutorial tells you how to make a custom jquery paginator in your liferay portlet.
This example is about photoalbums, but the page can contain whatever in the <div “image”>

The jquery file is specified in header-portlet tag in the liferay-portlet.xml :

<header-portlet-javascript>/js/jquery-1.8.3.js </header-portlet-javascript>

or in the jsp directly (as you can see below)

The code in the ViewPhotos.jsp is:

<script type="text/javascript" src="${renderRequest.contextPath}/js/jquery-1.8.3.js"></script>

 images = ImageLocalServiceUtil.getAllImagesbyAlbumId(albumId);
	String albumName= (String) request.getAttribute("albumName");
%>
<div id="<portlet:namespace/><br />"><span style="color: blue;">Photogallery DEMO Version 0.X </span> 

<script type="text/javascript">
 var $jq = jQuery.noConflict(true); 
 $(document).ready(function(){
   $('#content').Pagination();
 }); </script>

<div id="wrapper-content">
<h2>Photo album Paginator</h2>

<div class="pagination">
 <ul>
 <li><a href="#" id="prev"><button>Previous</button></a>
 <li><a href="#" id="next"><button>Next</button></a></li>
 </ul>
 </div>

<div id="content">
 No images found.
<div class="image">

 <img class="center" src="/<%=albumName=>/<%=path%>" alt="" width="40%" />

Image:

</div>
</div> <!--  content -->
</div> <!--  wrapper-content -->
</div>  <!--  portletnamespace -->

Remember to wrap it all with :  <strong><div id=”<portlet:namespace/>”></strong>

In my demo the “albumName” folder specified in the image attribute src is set in the xml file:
/home/laura/project/liferay-portal-6.1.0-ce-ga1/tomcat-7.0.23/conf/Catalina/localhost/albumName.xml

The content of the xml file is something the following:

<?xml version=”1.0″ encoding=”UTF-8″?>
<Context path=”/albumName” docBase=”/home/laura/albums/albumName” reloadable=”true”/>

albumName” might be something like “birthday_Party_Laura_2013

the jquery plugin (that I’ve placed in the main.js file) is the following:

(function($) {

	// Attach a new method to jQuery
	$.fn.extend({
		// PluginName - Pagination
		Pagination : function(options) {
			console.log("plugin");
			// Set the default values, use comma to separate the settings,
			// example:
			var defaults = {
					fadeSpeed : 100
			};

			// options can be extended when the plugin is invoked
			var options = $.extend(defaults, options);

			// Creating a reference to the object
			var objContent = $(this);

			// child div of the "content" one
			var imageDivList = new Array();
			var lastPage = 1;
			var paginatedPages;

			// initialization function
			init = function() { // for each div
				$('.image').each(function() {
					imageDivList.push(this);
				});

				// objContent.children().hide();
				$('.image').hide();

				console.log($(imageDivList).length);
				// show first page (lastPage=1)
				showPage(lastPage);

				// draw controls
				showPagination($(imageDivList).length);

			}; // end init function

			// show page function
			showPage = function(page) {
				i = page - 1;
				if (imageDivList[i]) {
					console.log(i);
					// hiding old page, display new one
					$(imageDivList[lastPage]).fadeOut(options.fadeSpeed);
					lastPage = i;
					$(imageDivList[lastPage]).fadeIn(options.fadeSpeed);

				}
			};

			// show pagination function (draw switching numbers)
			showPagination = function(numPages) {
				var pagins = '';
				for ( var i = 1; i <= numPages; i++) {
					pagins += '<li><a href="#" onclick="showPage(' + i
							+ '); return false;"><button>' + i + '</button></a></li>';
				} //     
	           
				// after the firt element, with id="prev", append the list with
				// the page number links
				$('.pagination li:first-child').after(pagins);
			};

			// perform initialization
			init();

			// and binding 2 events - on clicking to Prev
			$('.pagination #prev').click(function() {
				showPage(lastPage);
			});
			// and Next
			$('.pagination #next').click(function() {
				showPage(lastPage + 2);
			});

		}
	});
	// pass jQuery to the function,
})(jQuery);

The css for the paginator buttons, that I have specified in the main.css file is:

ul, li {
    list-style-type: none;
    margin-left:40px;
}

.pagination {
    clear: both;
    padding:0;
  /* width:250px; */
}

.pagination li {
    float:left;   
        margin-left: 0 auto;
}


Liferay search container pagination problem when passing form parameter SOLVED

Hello, guys!
I’ve been struggling for a couple of days trying to make my seach container pagination works.
When you clicking on the next page and you need to use a form parameter value submitted to get the rows, you need to store it in the portlet preferences, otherwise you lose it in the page “refresh”.

I haven’t found a solution on the web so far, so I’m posting my code snippets… that WORKS lol:
but I’m using portlet preferences … check it out!

[b]action method in the controller:[/b]

		public void searchVolume(ActionRequest request, ActionResponse response)
			throws IOException, PortletException, PortalException,
			SystemException, NoSuchVolumeException {

		String volumeIdentifier = request.getParameter("volumeId");
		long volumeId = (long) Integer.parseInt(volumeIdentifier);
		long idVol = 0;

		boolean found = false;
		boolean emptyList = false;

		List volume = new ArrayList();
		volume = VolumeLocalServiceUtil.getAllVolumes();
		List caseArchive = new ArrayList();
		caseArchive = CaseArchiveLocalServiceUtil
				.getAllCasesbyVolumeId(volumeId);

		if (caseArchive.size() == 0) {
			emptyList = true;
		}

		for (Volume itemVolume : volume) {
			if (itemVolume.getVolumeId() == volumeId)
				found = true;
		}

		if (found && emptyList) {
			SessionMessages.add(request, "no-cases-found");
		} else if (found && !emptyList) {
			Volume vol = DBUtil.getVolumefromRequest(request);
			idVol = vol.getVolumeId();

			if (idVol == 1) {
				System.out.println("Volume id iniziale: " + volumeId);
				SessionErrors.add(request, "error-volume");
			} else if (SearchValidator.volumeNotNull(idVol) && !(idVol == 1))

			{
				System.out.println("Volume id action : " + vol.getVolumeId());

				response.setRenderParameter("volId", volumeIdentifier);
				System.out.println("search volume clicked");

				PortletPreferences prefs = request.getPreferences();
				String volumeIdent = request.getParameter("volumeId");
				if (volumeIdent != null) {
					prefs.setValue("volumeIdPref", volumeIdent);
					prefs.store();
				}

				VolumeLocalServiceUtil.clearService();

				SessionMessages.add(request, "search-volume");

			}
		} else
			SessionErrors.add(request, "error-volume");

		response.setRenderParameter("jspPage", viewDatabaseJSP);

	}

[b]JSP page[/b]:


	CaseArchiveLocalServiceUtil.clearCache();
	VolumeLocalServiceUtil.clearCache();

	//RoiLocalServiceUtil.clearCache();
	//ImageDBLocalServiceUtil.clearCache();
	//DicomLocalServiceUtil.clearCache();
	ImageTypeLocalServiceUtil.clearCache();

	List volumes = VolumeLocalServiceUtil.getAllVolumes();
	List cases = CaseArchiveLocalServiceUtil.getAllCases();
	Long volumeIdentifier = 1L;

	Collections.sort(volumes, new Comparator() {
		public int compare(Volume o1, Volume o2) {
			Volume p1 = (Volume) o1;
			Volume p2 = (Volume) o2;
			return p1.getVolumeName().compareToIgnoreCase(
					p2.getVolumeName());
		}
	});

	PortletURL portletURL = renderResponse.createRenderURL();

	portletURL.setParameter("jspPage", "/html/admin/viewDatabase.jsp");

	int selected = 0;
	String volSel = null;

	PortletPreferences prefs = renderRequest.getPreferences();
	String volumeId = (String) prefs.getValue("volumeIdPref", "1");
%>

	method="post">

		 1) {
						volumeIdentifier = (long) Integer.parseInt(volumeId);

					}

					List tempResults = DBUtil
							.getAllCasesOk(volumeIdentifier);

					results = ListUtil.subList(tempResults,
							searchContainer.getStart(),
							searchContainer.getEnd());

					total = tempResults.size();

					pageContext.setAttribute("results", results);
					pageContext.setAttribute("total", total);

					portletURL.setParameter("cur",
							searchContainer.getCurParam());
					System.out.println("Cur PRINT:" + searchContainer.getCur());
		%>

					href="" name='view Case' />

 <a href="<%=cancelURL%>">← Back to Menu</a>

In the example above, volumeId is the form action parameter (passed by the select option), while volumeIdPref is the portlet preferences parameter, which keeps the value while consulting the pages.
In the action method, that is invoked when submitting the form value, i’ve set a response parameter called volId which is used in the jsp to set the variable value when invoking the search-container result page “1”. The render parameter is null when visiting the other pages, but it can be retrieved by the portlet preferences value.

I hope this helps. Let me know if you have questions or suggestions.
Regards
Laura

Liferay Service Builder with external database

To make a Liferay Service Builder with external database there are some rules to follow. This post will help you to get straight to the point.
Keep in mind that:

  • You can’t deploy more than one portlet mapping column with the same entity name, otherwise you get a hot-Deployment error.
  • the names of the portlet name, namespace and database must be distinct (ex. portlet=”imageview“, namespace=”mammography“, database=”dicomviewer“).
  • when you add external jar, you must add them in the Tomcat/lib/ext
    so liferay can find them in the global classpath.

The steps to make the service builder with the external database mapping are:

  1. make the service.xml file in the /docroot/WEB-INF/
  2. launch the build-service ant command
  3. add the ext-spring.xml file in the /docroot/WEB-INF/src/META-INF/ folder
  4. deploy the portlet.

The example below might be helpful.

—service.xml ————

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.0.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_0_0.dtd">


<service-builder package-path="it.dicom">
<author>Laura Liparulo</author>
<namespace>mammography</namespace>

<entity name="Volume" local-service="true" remote-service="true" table="volume"
data-source="mammographyDataSource" session-factory="mammographySessionFactory" tx-manager="mammographyTransactionManager">
<!-- PK Fields -->
<column name="volumeId" type="long" primary="true" />
<!-- Other Fields -->
<column name="volumeName" type="String" />
<!-- Relationships -->
<column name="caseVolume" type="Collection" entity="CaseArchive"
mapping-key="volumeId" />
<order by="asc">
<order-column name="volumeName" />

</order>
<finder name="Volume_Name" return-type="Collection">
<finder-column name="volumeName" />
</finder>
</entity>

<entity name="CaseArchive" local-service="true" remote-service="true" table="case_archive"
data-source="mammographyDataSource" session-factory="mammographySessionFactory" tx-manager="mammographyTransactionManager">
<!-- PK Fields -->
<column name="caseId" type="long" primary="true" />
<!-- Other Fields -->
<column name="caseName" type="String" />
<column name="volumeId" type="long" />
<column name="notes" type="String" />
<!-- Relationships -->
<column name="image_Case" type="Collection" entity="Image"
mapping-key="caseId" />
<order by="asc">
<order-column name="caseName" />
</order>
<finder name="Case_Name" return-type="Collection">
<finder-column name="caseName" />

</finder>
</entity>

</service-builder>
;

—ext-spring.xml ————

<?xml version="1.0"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean
class="
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</bean>
<bean id="mammographyDataSourceTarget"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dicomviewer" />
<property name="username" value="root" />

<property name="password" value="tigertailz" />
</bean>
<bean id="mammographyDataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref bean="mammographyDataSourceTarget" />
</property>
</bean>
<bean id="mammographyHibernateSessionFactory"
class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration">
<property name="dataSource">
<ref bean="mammographyDataSource" />
</property>
</bean>
<bean id="mammographySessionFactory">
<property name="sessionFactoryImplementor">
<ref bean="mammographyHibernateSessionFactory" />

</property>
</bean>
<bean id="mammographyTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="dataSource">
<ref bean="mammographyDataSource" />
</property>
<property name="sessionFactory">
<ref bean="mammographyHibernateSessionFactory" />
</property>
</bean>
</beans>

Now you can make it fast as a shark! 🙂

WordPress: How to remove items in the administration dashboards

Yeah, you have understood that this blog is powered by WordPress.

Surfing the web, I have found plugins and posts about removing items from the wordpress dashboard.

Loggin as administrator, i’ve tried a plugin called: “remove-posts-from-admin”, but that doesn’t remove the comments.

I’ve tried some code modifications suggested by other bloggers, so I’ve found a way to make it.

Nobody tells it straight. So here it is :-). You have to modify a file in your theme folder:

/www/wp-content/themes/yourtheme/functions.php

To remove “posts” and “comments” simply add this code at the end of the file:

 

 

add_action( 'admin_menu', 'remove_links_menu' );
function remove_links_menu() {
remove_menu_page('index.php'); // Dashboard
// remove_menu_page('edit.php'); // Posts
// remove_menu_page('upload.php'); // Media
// remove_menu_page('link-manager.php'); // Links
// remove_menu_page('edit.php?post_type=page'); // Pages
remove_menu_page('edit-comments.php'); // Comments
// remove_menu_page('themes.php'); // Appearance
// remove_menu_page('plugins.php'); // Plugins
// remove_menu_page('users.php'); // Users
//remove_menu_page('tools.php'); // Tools
// remove_menu_page('options-general.php'); // Settings
}
?>

 

 

Another way is the following. This is a core modification and may cause incompatibility problems if you want to upgrade. Anyway it works:

You simply need to edit the file called menu.php in the wp-admin directory.

I’ve commented the “posts” and “comments” sections and moved Pages to the top (changed the number in the array, $menu[5] is now Posts) :

$menu[5] = array( __('Pages'), 'edit_pages', 'edit.php?post_type=page', '', 'menu-top menu-icon-page', 'menu-pages', 'div' );
$submenu['edit.php?post_type=page'][5] = array( __('All Pages'), 'edit_pages', 'edit.php?post_type=page' );
/* translators: add new page */
$submenu['edit.php?post_type=page'][10] = array( _x('Add New', 'page'), 'edit_pages', 'post-new.php?post_type=page' );
$i = 15;
foreach ( get_taxonomies( array(), 'objects' ) as $tax ) {
if ( ! $tax->show_ui || ! in_array('page', (array) $tax->object_type, true) )
continue;

$submenu['edit.php?post_type=page'][$i++] = array( esc_attr( $tax->labels->menu_name ), $tax->cap->manage_terms, 'edit-tags.php?taxonomy=' . $tax->name . '&post_type=page' );
}
unset($tax);

$awaiting_mod = wp_count_comments();

$awaiting_mod = $awaiting_mod->moderated;

To remove a section you must comment the piece of code, adding /* at the beginning and */ at the end. Like this:

POSTS:
/*$menu[5] = array( __('Posts'), 'edit_posts', 'edit.php', '', 'open-if-no-js menu-top menu-icon-post', 'menu-posts', 'div' );
$submenu['edit.php'][5] = array( __('All Posts'), 'edit_posts', 'edit.php' );
/* translators: add new post */ /*
$submenu['edit.php'][10] = array( _x('Add New', 'post'), 'edit_posts', 'post-new.php' );

$i = 15;
foreach ( get_taxonomies( array(), 'objects' ) as $tax ) {
if ( ! $tax->show_ui || ! in_array('post', (array) $tax->object_type, true) )
continue;

$submenu['edit.php'][$i++] = array( esc_attr( $tax->labels->menu_name ), $tax->cap->manage_terms, 'edit-tags.php?taxonomy=' . $tax->name );
}
unset($tax); */

COMMENTS:

/*$menu[25] = array( sprintf( __('Comments %s'), "" . number_format_i18n($awaiting_mod) . "" ), 'edit_posts', 'edit-comments.php', '', 'menu-top menu-icon-comments', 'menu-comments', 'div' );
unset($awaiting_mod);

$submenu[ 'edit-comments.php' ][0] = array( __('All Comments'), 'edit_posts', 'edit-comments.php' );

$_wp_last_object_menu = 25; // The index of the last top-level menu in the object menu group
*/

Easy, right?

Recursive Beer Ballad

Even though I’ve been into Java since 2007, I had never found out how recursion can be powerful when you have to print several lines of code…

So now I’ve just made a funny little programs with a recursive method.

Separating the cases by a switch, this funny Beer Ballad plays even better!

Check it out!

—————————————————–// BeerBallad.java”//———————




import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Beer {

public static void balladCounter(int n) {
switch(n){
case 0:  System.out.println("No bottles of beer on the wall, no bottles of beer, ya’ can’t take one down, ya’    can’t pass it around, ’cause there are no more bottles of beer on the wall! \n"); break;
case 1:  System.out.println("1 bottle of beer on the wall, 1 bottle of beer,  ya’ take one down, ya’ pass it around, and now there are no more bottles of beer on the wall! \n");
balladCounter(n-1);   break;
case 2:    System.out.println("2 bottles of beer on the wall, 2 bottles of beer,  ya’ take one down, ya’ pass it around, and now just 1 bottle of beer on the wall! \n");
balladCounter(n-1);     break;
default:     // if n>2
System.out.println(n+" bottles of beer on the wall, "+n+" bottles of beer, ya’ take one down, ya’ pass it around, "+(n-1)+" bottles of beer on the wall. \n");
balladCounter(n-1);    break;
}
}

public static void main(String[] args) {
int m = 0;   //input from console
String inputString = null;
BufferedReader bufferedReader = null;
System.out.println("How many beers do you want to sing about?");
bufferedReader = new BufferedReader(new InputStreamReader(System.in));

try { inputString = bufferedReader.readLine();


m = Integer.parseInt(inputString);

System.out.println("\n THE BALLAD OF THE BEER \n");
balladCounter(m); }
catch (IOException e) { e.printStackTrace();}
}
} 

Perl script using LWP module

Library FOR WWW in Perl (LWP)

In Linux you can istall all the perl modules about the web (LWP, URI, URL, HTTP…) at once:

:~$ sudo apt-get install libwww-perl

LWP is the most used Perl module for accessing data on the web.

LWP::Simple – module to get document by http
its functions don’t support cookies or authorization, setting header lines in the HTTP request; and generally, they don’t support reading header lines in the HTTP response (most notably the full HTTP error message, in case of an error). To get at all those features, you’ll have to use the LWP::UserAgent;

LWP::UserAgent is a class for “virtual browsers,” which you use for performing requests, and HTTP::Response is a class for the responses (or error messages) that you get back from those requests.

There are two objects involved: $browser, which holds an object of the class LWP::UserAgent, and then the $response object, which is of the class HTTP::Response. You really need only one browser object per program; but every time you make a request, you get back ar esponse object, which will have some interesting attributes:

$response->is_success : A HTTP status line, indicating success or failure  (like “404 Not Found”).

$response->content_type A MIME content-type like “text/html”, “image/gif”, “application/xml”, and so on, which you can see with

$response->content : the actual content of the response. If the response is HTML, that’s where the HTML source will be; if it’s a GIF, then $response->content will be the binary GIF data.

Enabling Cookies

A default LWP::UserAgent object acts like a browser with its cookies support turned off.
You can even activate cookies, with the following function:

$browser->cookie_jar({});

with “cookie_jar” you can get and save the cookies from Browsers.

The following script gets a url from the shell and print the content of the corresponding web page both to screen and a new file called “code.html” (created by running the script).

———————————————————-webclient.pl———————————–

#!/usr/bin/perl -w
use LWP::UserAgent;

#browser = instance of the UserAgent class
my $browser = LWP::UserAgent->new;
my $url =$ARGV[0]; # passing the url by command line
my $response = $browser->get($url);

die "Can’t get $url \n", $response->status_line
unless $response->is_success;

# check if the content is html
die "Hey, I was expecting HTML, not ", $response->content_type
unless $response->content_type eq 'text/html';

print "Page content: \n";

#print content to console
print $response->decoded_content;

#print content to a NEW file
open (MYPAGE, '>>code.html');
print MYPAGE $response->decoded_content;
close (MYPAGE);

#REGULAR EXPRESSION: search for a string in the content
if($response->content =~ m/perl/i) {
print " \n \n This page is about Perl!\n \n";
} else {print "\n \n No content about Perl! \n \n"; }

We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners.
Cookies settings
Accept
Privacy & Cookie policy
Privacy & Cookies policy
Cookie name Active

Privacy Policy

What information do we collect?

We collect information from you when you register on our site or place an order. When ordering or registering on our site, as appropriate, you may be asked to enter your: name, e-mail address or mailing address.

What do we use your information for?

Any of the information we collect from you may be used in one of the following ways: To personalize your experience (your information helps us to better respond to your individual needs) To improve our website (we continually strive to improve our website offerings based on the information and feedback we receive from you) To improve customer service (your information helps us to more effectively respond to your customer service requests and support needs) To process transactions Your information, whether public or private, will not be sold, exchanged, transferred, or given to any other company for any reason whatsoever, without your consent, other than for the express purpose of delivering the purchased product or service requested. To administer a contest, promotion, survey or other site feature To send periodic emails The email address you provide for order processing, will only be used to send you information and updates pertaining to your order.

How do we protect your information?

We implement a variety of security measures to maintain the safety of your personal information when you place an order or enter, submit, or access your personal information. We offer the use of a secure server. All supplied sensitive/credit information is transmitted via Secure Socket Layer (SSL) technology and then encrypted into our Payment gateway providers database only to be accessible by those authorized with special access rights to such systems, and are required to?keep the information confidential. After a transaction, your private information (credit cards, social security numbers, financials, etc.) will not be kept on file for more than 60 days.

Do we use cookies?

Yes (Cookies are small files that a site or its service provider transfers to your computers hard drive through your Web browser (if you allow) that enables the sites or service providers systems to recognize your browser and capture and remember certain information We use cookies to help us remember and process the items in your shopping cart, understand and save your preferences for future visits, keep track of advertisements and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business. If you prefer, you can choose to have your computer warn you each time a cookie is being sent, or you can choose to turn off all cookies via your browser settings. Like most websites, if you turn your cookies off, some of our services may not function properly. However, you can still place orders by contacting customer service. Google Analytics We use Google Analytics on our sites for anonymous reporting of site usage and for advertising on the site. If you would like to opt-out of Google Analytics monitoring your behaviour on our sites please use this link (https://tools.google.com/dlpage/gaoptout/)

Do we disclose any information to outside parties?

We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our website, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.

Registration

The minimum information we need to register you is your name, email address and a password. We will ask you more questions for different services, including sales promotions. Unless we say otherwise, you have to answer all the registration questions. We may also ask some other, voluntary questions during registration for certain services (for example, professional networks) so we can gain a clearer understanding of who you are. This also allows us to personalise services for you. To assist us in our marketing, in addition to the data that you provide to us if you register, we may also obtain data from trusted third parties to help us understand what you might be interested in. This ‘profiling’ information is produced from a variety of sources, including publicly available data (such as the electoral roll) or from sources such as surveys and polls where you have given your permission for your data to be shared. You can choose not to have such data shared with the Guardian from these sources by logging into your account and changing the settings in the privacy section. After you have registered, and with your permission, we may send you emails we think may interest you. Newsletters may be personalised based on what you have been reading on theguardian.com. At any time you can decide not to receive these emails and will be able to ‘unsubscribe’. Logging in using social networking credentials If you log-in to our sites using a Facebook log-in, you are granting permission to Facebook to share your user details with us. This will include your name, email address, date of birth and location which will then be used to form a Guardian identity. You can also use your picture from Facebook as part of your profile. This will also allow us and Facebook to share your, networks, user ID and any other information you choose to share according to your Facebook account settings. If you remove the Guardian app from your Facebook settings, we will no longer have access to this information. If you log-in to our sites using a Google log-in, you grant permission to Google to share your user details with us. This will include your name, email address, date of birth, sex and location which we will then use to form a Guardian identity. You may use your picture from Google as part of your profile. This also allows us to share your networks, user ID and any other information you choose to share according to your Google account settings. If you remove the Guardian from your Google settings, we will no longer have access to this information. If you log-in to our sites using a twitter log-in, we receive your avatar (the small picture that appears next to your tweets) and twitter username.

Children’s Online Privacy Protection Act Compliance

We are in compliance with the requirements of COPPA (Childrens Online Privacy Protection Act), we do not collect any information from anyone under 13 years of age. Our website, products and services are all directed to people who are at least 13 years old or older.

Updating your personal information

We offer a ‘My details’ page (also known as Dashboard), where you can update your personal information at any time, and change your marketing preferences. You can get to this page from most pages on the site – simply click on the ‘My details’ link at the top of the screen when you are signed in.

Online Privacy Policy Only

This online privacy policy applies only to information collected through our website and not to information collected offline.

Your Consent

By using our site, you consent to our privacy policy.

Changes to our Privacy Policy

If we decide to change our privacy policy, we will post those changes on this page.
Save settings
Cookies settings