<commit_before>/*******************************************************************************
 * Copyright (c) 2004, 2007 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.engine.presentation;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.format.DateFormatter;
import org.eclipse.birt.core.format.NumberFormatter;
import org.eclipse.birt.core.format.StringFormatter;
import org.eclipse.birt.core.template.TextTemplate;
import org.eclipse.birt.data.engine.api.IBaseQueryDefinition;
import org.eclipse.birt.report.engine.api.CachedImage;
import org.eclipse.birt.report.engine.api.EngineConstants;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IHTMLImageHandler;
import org.eclipse.birt.report.engine.api.IImage;
import org.eclipse.birt.report.engine.api.IRenderOption;
import org.eclipse.birt.report.engine.api.impl.Image;
import org.eclipse.birt.report.engine.content.ContentVisitorAdapter;
import org.eclipse.birt.report.engine.content.ICellContent;
import org.eclipse.birt.report.engine.content.IContent;
import org.eclipse.birt.report.engine.content.IDataContent;
import org.eclipse.birt.report.engine.content.IForeignContent;
import org.eclipse.birt.report.engine.content.IImageContent;
import org.eclipse.birt.report.engine.content.ILabelContent;
import org.eclipse.birt.report.engine.content.IListContent;
import org.eclipse.birt.report.engine.content.IPageContent;
import org.eclipse.birt.report.engine.content.IReportContent;
import org.eclipse.birt.report.engine.content.IRowContent;
import org.eclipse.birt.report.engine.content.IStyle;
import org.eclipse.birt.report.engine.content.ITableContent;
import org.eclipse.birt.report.engine.content.ITextContent;
import org.eclipse.birt.report.engine.css.engine.value.css.CSSValueConstants;
import org.eclipse.birt.report.engine.executor.ExecutionContext;
import org.eclipse.birt.report.engine.executor.template.TemplateExecutor;
import org.eclipse.birt.report.engine.extension.IBaseResultSet;
import org.eclipse.birt.report.engine.extension.IQueryResultSet;
import org.eclipse.birt.report.engine.extension.IReportItemPresentation;
import org.eclipse.birt.report.engine.extension.IRowSet;
import org.eclipse.birt.report.engine.extension.internal.ExtensionManager;
import org.eclipse.birt.report.engine.extension.internal.RowSet;
import org.eclipse.birt.report.engine.extension.internal.SingleRowSet;
import org.eclipse.birt.report.engine.ir.ExtendedItemDesign;
import org.eclipse.birt.report.engine.ir.ListItemDesign;
import org.eclipse.birt.report.engine.ir.ReportItemDesign;
import org.eclipse.birt.report.engine.ir.TextItemDesign;
import org.eclipse.birt.report.engine.script.internal.OnRenderScriptVisitor;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.ExtendedItemHandle;
import org.eclipse.birt.report.model.api.IResourceLocator;
import org.eclipse.birt.report.model.api.ModuleUtil;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.ReportElementHandle;
import org.w3c.dom.css.CSSValue;

import com.ibm.icu.util.ULocale;


public class LocalizedContentVisitor extends ContentVisitorAdapter
{
	
	protected static Logger logger = Logger
			.getLogger( LocalizedContentVisitor.class.getName( ) );
	
	private ExecutionContext context;
	private Locale locale;
	private String outputFormat;
	protected HashMap templates = new HashMap( );
	private OnRenderScriptVisitor onRenderVisitor;
	
	public LocalizedContentVisitor( ExecutionContext context )
	{
		this.context = context;
		this.locale = context.getLocale( );
		this.outputFormat = context.getOutputFormat( );
		this.onRenderVisitor = new OnRenderScriptVisitor( context );
	}
	
	IReportContent getReportContent( )
	{
		return context.getReportContent( );
	}

	ReportDesignHandle getReportDesign( )
	{
		return context.getDesign( );
	}
	
	/**
	 * Checks the background image property. If it is given as a relative path,
	 * gets its absolute path and sets it back to the style.
	 * 
	 * @param style
	 *            the style that defines background image related properties
	 */
	protected void processBackgroundImage( IStyle style )
	{
		if ( style == null )
			return;

		String image = style.getBackgroundImage( );
		if ( image == null )
			return;

		ReportDesignHandle reportDesign = context.getDesign( );
		if ( reportDesign != null )
		{
			URL url = reportDesign.findResource( image, IResourceLocator.IMAGE );
			if ( url != null )
			{
				style.setBackgroundImage( url.toExternalForm( ) );
			}
		}
	}
	
	public IContent localize(IContent content)
	{
		IStyle style = content.getInlineStyle( );
		processBackgroundImage( style );
		Object value = content.accept( this, content );
		return (IContent) value;
	}
	
	protected IContent localizeAllChildren( IContent content )
	{
		ArrayList children = (ArrayList) content.getChildren( );
		if ( children != null )
		{			
			for ( int i = 0; i < children.size( ); i++ )
			{
				IContent child = (IContent) children.get( i );
				IContent localChild = localize( child );
				if ( localChild != child )
				{
					// replace the child with the licallized child.
					children.set( i, localChild );

					// set the locallized child's parent as orient child's
					// parent.
					localChild.setParent( content );

					// copy all children of this child to its localized child,
					// also change all children's parent to this localized
					// child.
					Collection childrenOfLocalChild = localChild.getChildren( );
					Iterator iter = child.getChildren( ).iterator( );
					while ( iter.hasNext( ) )
					{
						IContent childOfChild = (IContent) iter.next( );
						if ( !childrenOfLocalChild.contains( childOfChild ) )
						{
							childOfChild.setParent( localChild );
							childrenOfLocalChild.add( childOfChild );
						}
					}
				}
				localizeAllChildren( localChild );
			}
		}
		return content;
	}

	public Object visitPage( IPageContent page, Object value )
	{
		return page;
	}
	
	protected TextTemplate parseTemplate( String text )
	{
		SoftReference templateRef = (SoftReference) templates.get( text );
		TextTemplate template = null;
		if ( templateRef != null )
		{
			template = (TextTemplate) templateRef.get( );
			if ( template != null )
			{
				return template;
			}
		}
		try
		{
			template = new org.eclipse.birt.core.template.TemplateParser( )
					.parse( text );
			templateRef = new SoftReference( template );
			templates.put( text, templateRef );
		}
		catch ( Exception ex )
		{
			context
					.addException( new EngineException( ex
							.getLocalizedMessage( ) ) );
			logger.log( Level.WARNING, ex.getMessage( ), ex );
		}
		return template;
	}

	String executeTemplate( TextTemplate template, HashMap values )
	{
		return new TemplateExecutor( context ).execute( template, values );
	}

	public Object visitList( IListContent list, Object value)
	{
		if ( list.getGenerateBy( ) instanceof ListItemDesign )
		{
			handleOnRender( list );
		}
		return list;
	}

	public Object visitTable( ITableContent table, Object value )
	{
		handleOnRender( table );
		
		String captionText = table.getCaption( );
		String captionKey = table.getCaptionKey( );

		captionText = localize( table, captionKey, captionText );
		table.setCaption( captionText );
		
		return table;
	}

	public Object visitRow( IRowContent row, Object value )
	{
		handleOnRender( row );
		return row;
	}

	public Object visitCell( ICellContent cell, Object value )
	{
		handleOnRender( cell );
		return cell;
	}

	/**
	 * handle the data content.
	 * 
	 * @param data
	 *            data content object
	 */
	public Object visitData( IDataContent data, Object value )
	{
		handleOnRender( data );
		processData( data );
		return data;
	}

	/**
	 * process the data content
	 * 
	 * <li> localize the help text
	 * <li> format the value
	 * <li> handle it as it is an text.
	 * 
	 * @param data
	 *            data object
	 */
	protected void processData( IDataContent data )
	{
		String helpText = localize( data, data.getHelpKey( ), data.getHelpText( ) );
		data.setHelpText( helpText );
		String text = ""; //$NON-NLS-1$
		if ( data.getLabelKey( ) != null || data.getLabelText( ) != null )
		{
			text = localize( data, data.getLabelKey( ), data.getLabelText( ) );
		}
		else
		{
			Object value = data.getValue( );
			if ( value != null )
			{
				IStyle style = data.getComputedStyle( );
				if ( value instanceof Number )
				{
					String format = style.getNumberFormat( );
					NumberFormatter fmt = context.getNumberFormatter( format );
					text = fmt.format( (Number) value );
					CSSValue align = style
							.getProperty( IStyle.STYLE_NUMBER_ALIGN );
					if ( align != null && align != CSSValueConstants.NONE_VALUE )
					{
						data.getStyle( ).setProperty( IStyle.STYLE_TEXT_ALIGN,
								align );
					}
				}
				else if ( value instanceof String )
				{
					StringFormatter fmt = context.getStringFormatter( style
							.getStringFormat( ) );
					text = fmt.format( (String) value );

				}
				else if ( value instanceof Date )
				{
					DateFormatter fmt = context.getDateFormatter( style
							.getDateFormat( ) );
					text = fmt.format( (Date) value );
				}
				else
				{
					text = value.toString( );
				}
			}
		}
		//text can be null value after applying format
		if(text!=null)
		{
			data.setText( text );
		}
		else
		{
			data.setText( "" ); //$NON-NLS-1$
		}
			
			

	}

	/**
	 * handle the label.
	 * 
	 * @param label
	 *            label content
	 */
	public Object visitLabel( ILabelContent label, Object value )
	{
		handleOnRender( label );
		processLabel( label );
		return label;
	}

	/**
	 * process the label content
	 * 
	 * <li> localize the help text
	 * <li> localize the label content<commit_msg>fix bug 201526: Mutil parameter value will show the mutil value[0705]<commit_after>/*******************************************************************************
 * Copyright (c) 2004, 2007 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.engine.presentation;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.format.DateFormatter;
import org.eclipse.birt.core.format.NumberFormatter;
import org.eclipse.birt.core.format.StringFormatter;
import org.eclipse.birt.core.template.TextTemplate;
import org.eclipse.birt.data.engine.api.IBaseQueryDefinition;
import org.eclipse.birt.report.engine.api.CachedImage;
import org.eclipse.birt.report.engine.api.EngineConstants;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IHTMLImageHandler;
import org.eclipse.birt.report.engine.api.IImage;
import org.eclipse.birt.report.engine.api.IRenderOption;
import org.eclipse.birt.report.engine.api.impl.Image;
import org.eclipse.birt.report.engine.content.ContentVisitorAdapter;
import org.eclipse.birt.report.engine.content.ICellContent;
import org.eclipse.birt.report.engine.content.IContent;
import org.eclipse.birt.report.engine.content.IDataContent;
import org.eclipse.birt.report.engine.content.IForeignContent;
import org.eclipse.birt.report.engine.content.IImageContent;
import org.eclipse.birt.report.engine.content.ILabelContent;
import org.eclipse.birt.report.engine.content.IListContent;
import org.eclipse.birt.report.engine.content.IPageContent;
import org.eclipse.birt.report.engine.content.IReportContent;
import org.eclipse.birt.report.engine.content.IRowContent;
import org.eclipse.birt.report.engine.content.IStyle;
import org.eclipse.birt.report.engine.content.ITableContent;
import org.eclipse.birt.report.engine.content.ITextContent;
import org.eclipse.birt.report.engine.css.engine.value.css.CSSValueConstants;
import org.eclipse.birt.report.engine.executor.ExecutionContext;
import org.eclipse.birt.report.engine.executor.template.TemplateExecutor;
import org.eclipse.birt.report.engine.extension.IBaseResultSet;
import org.eclipse.birt.report.engine.extension.IQueryResultSet;
import org.eclipse.birt.report.engine.extension.IReportItemPresentation;
import org.eclipse.birt.report.engine.extension.IRowSet;
import org.eclipse.birt.report.engine.extension.internal.ExtensionManager;
import org.eclipse.birt.report.engine.extension.internal.RowSet;
import org.eclipse.birt.report.engine.extension.internal.SingleRowSet;
import org.eclipse.birt.report.engine.ir.ExtendedItemDesign;
import org.eclipse.birt.report.engine.ir.ListItemDesign;
import org.eclipse.birt.report.engine.ir.ReportItemDesign;
import org.eclipse.birt.report.engine.ir.TextItemDesign;
import org.eclipse.birt.report.engine.script.internal.OnRenderScriptVisitor;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.ExtendedItemHandle;
import org.eclipse.birt.report.model.api.IResourceLocator;
import org.eclipse.birt.report.model.api.ModuleUtil;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.ReportElementHandle;
import org.w3c.dom.css.CSSValue;

import com.ibm.icu.util.ULocale;


public class LocalizedContentVisitor extends ContentVisitorAdapter
{
	
	protected static Logger logger = Logger
			.getLogger( LocalizedContentVisitor.class.getName( ) );
	
	private ExecutionContext context;
	private Locale locale;
	private String outputFormat;
	protected HashMap templates = new HashMap( );
	private OnRenderScriptVisitor onRenderVisitor;
	
	public LocalizedContentVisitor( ExecutionContext context )
	{
		this.context = context;
		this.locale = context.getLocale( );
		this.outputFormat = context.getOutputFormat( );
		this.onRenderVisitor = new OnRenderScriptVisitor( context );
	}
	
	IReportContent getReportContent( )
	{
		return context.getReportContent( );
	}

	ReportDesignHandle getReportDesign( )
	{
		return context.getDesign( );
	}
	
	/**
	 * Checks the background image property. If it is given as a relative path,
	 * gets its absolute path and sets it back to the style.
	 * 
	 * @param style
	 *            the style that defines background image related properties
	 */
	protected void processBackgroundImage( IStyle style )
	{
		if ( style == null )
			return;

		String image = style.getBackgroundImage( );
		if ( image == null )
			return;

		ReportDesignHandle reportDesign = context.getDesign( );
		if ( reportDesign != null )
		{
			URL url = reportDesign.findResource( image, IResourceLocator.IMAGE );
			if ( url != null )
			{
				style.setBackgroundImage( url.toExternalForm( ) );
			}
		}
	}
	
	public IContent localize(IContent content)
	{
		IStyle style = content.getInlineStyle( );
		processBackgroundImage( style );
		Object value = content.accept( this, content );
		return (IContent) value;
	}
	
	protected IContent localizeAllChildren( IContent content )
	{
		ArrayList children = (ArrayList) content.getChildren( );
		if ( children != null )
		{			
			for ( int i = 0; i < children.size( ); i++ )
			{
				IContent child = (IContent) children.get( i );
				IContent localChild = localize( child );
				if ( localChild != child )
				{
					// replace the child with the licallized child.
					children.set( i, localChild );

					// set the locallized child's parent as orient child's
					// parent.
					localChild.setParent( content );

					// copy all children of this child to its localized child,
					// also change all children's parent to this localized
					// child.
					Collection childrenOfLocalChild = localChild.getChildren( );
					Iterator iter = child.getChildren( ).iterator( );
					while ( iter.hasNext( ) )
					{
						IContent childOfChild = (IContent) iter.next( );
						if ( !childrenOfLocalChild.contains( childOfChild ) )
						{
							childOfChild.setParent( localChild );
							childrenOfLocalChild.add( childOfChild );
						}
					}
				}
				localizeAllChildren( localChild );
			}
		}
		return content;
	}

	public Object visitPage( IPageContent page, Object value )
	{
		return page;
	}
	
	protected TextTemplate parseTemplate( String text )
	{
		SoftReference templateRef = (SoftReference) templates.get( text );
		TextTemplate template = null;
		if ( templateRef != null )
		{
			template = (TextTemplate) templateRef.get( );
			if ( template != null )
			{
				return template;
			}
		}
		try
		{
			template = new org.eclipse.birt.core.template.TemplateParser( )
					.parse( text );
			templateRef = new SoftReference( template );
			templates.put( text, templateRef );
		}
		catch ( Exception ex )
		{
			context
					.addException( new EngineException( ex
							.getLocalizedMessage( ) ) );
			logger.log( Level.WARNING, ex.getMessage( ), ex );
		}
		return template;
	}

	String executeTemplate( TextTemplate template, HashMap values )
	{
		return new TemplateExecutor( context ).execute( template, values );
	}

	public Object visitList( IListContent list, Object value)
	{
		if ( list.getGenerateBy( ) instanceof ListItemDesign )
		{
			handleOnRender( list );
		}
		return list;
	}

	public Object visitTable( ITableContent table, Object value )
	{
		handleOnRender( table );
		
		String captionText = table.getCaption( );
		String captionKey = table.getCaptionKey( );

		captionText = localize( table, captionKey, captionText );
		table.setCaption( captionText );
		
		return table;
	}

	public Object visitRow( IRowContent row, Object value )
	{
		handleOnRender( row );
		return row;
	}

	public Object visitCell( ICellContent cell, Object value )
	{
		handleOnRender( cell );
		return cell;
	}

	/**
	 * handle the data content.
	 * 
	 * @param data
	 *            data content object
	 */
	public Object visitData( IDataContent data, Object value )
	{
		handleOnRender( data );
		processData( data );
		return data;
	}

	/**
	 * process the data content
	 * 
	 * <li> localize the help text
	 * <li> format the value
	 * <li> handle it as it is an text.
	 * 
	 * @param data
	 *            data object
	 */
	protected void processData( IDataContent data )
	{
		String helpText = localize( data, data.getHelpKey( ), data.getHelpText( ) );
		data.setHelpText( helpText );
		String text = ""; //$NON-NLS-1$
		if ( data.getLabelKey( ) != null || data.getLabelText( ) != null )
		{
			text = localize( data, data.getLabelKey( ), data.getLabelText( ) );
		}
		else
		{
			Object value = data.getValue( );

			if ( value instanceof Object[] )
			{
				Object[] values = (Object[]) value;
				if ( values.length > 0 )
				{
					value = values[0];
				}
				else
				{
					value = null;
				}
			}
			
			if ( value != null )
			{
				IStyle style = data.getComputedStyle( );
				if ( value instanceof Number )
				{
					String format = style.getNumberFormat( );
					NumberFormatter fmt = context.getNumberFormatter( format );
					text = fmt.format( (Number) value );
					CSSValue align = style
							.getProperty( IStyle.STYLE_NUMBER_ALIGN );
					if ( align != null && align != CSSValueConstants.NONE_VALUE )
					{
						data.getStyle( ).setProperty( IStyle.STYLE_TEXT_ALIGN,
								align );
					}
				}
				else if ( value instanceof String )
				{
					StringFormatter fmt = context.getStringFormatter( style
							.getStringFormat( ) );
					text = fmt.format( (String) value );

				}
				else if ( value instanceof Date )
				{
					DateFormatter fmt = context.getDateFormatter( style
							.getDateFormat( ) );
					text = fmt.format( (Date) value );
				}
				else
				{
					text = value.toString( );
				}
			}
		}
		// text can be null value after applying format
		if ( text != null )
		{
			data.setText( text );
		}
		else
		{
			data.setText( "" ); //$NON-NLS-1$
		}
	}

	/**
	 * handle the label.
	 * 
	 * @param label
	 *            label content
	 */
	public Object visitLabel( ILabelContent label, Object value )
	{
		handleOnRender( label );
		processLabel( label );
		return label;
	}

	/**
	 * process the label content
	 * 
	 * <li> localize the help text
	 * <li> localize the label content
{'fraction_non_alphanumeric': 0.12081930156386954, 'fraction_numerical': 0.002029801171748858, 'mean_word_length': 3.6629382662938266, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6039531', 'n_tokens_mistral': 7402, 'n_tokens_neox': 6431, 'n_words': 1493}