alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (MessageDenormalizerImpl.java)

This example Glassfish source code file (MessageDenormalizerImpl.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

body, bytearrayoutputstream, exception, exception, fault, io, log, logging, soap_namespace_prefix, soap_namespace_prefix, soapmessage, soapwrapper, soapwrapper, string, string, stringwriter, util, writer

The Glassfish MessageDenormalizerImpl.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.jbi.serviceengine.util.soap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;

import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jbi.messaging.Fault;
import javax.jbi.messaging.NormalizedMessage;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.AttachmentPart;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import javax.activation.DataHandler;

import java.util.logging.Logger;

/**
 * This Basic Profile 1.0 aware implementation is used to denormalize a JBI Normalized
 * Message and convert it into a SOAP message format.
 *
 * @author Sun Microsystems, Inc.
 */
public class MessageDenormalizerImpl implements MessageDenormalizer
{
    /**
     * Namespace prefix for the payload.
     */
    private static final String PAYLOAD_NAMESPACE_PREFIX = "jbisb0";

    /**
     * SOAP Namespace prefix.
     */
    private static final String SOAP_NAMESPACE_PREFIX = "soap";

    /**
     * XML Schema Instance prefix.
     */
    private static final String XML_SCHEMA_INSTANCE_NAMESPACE_PREFIX = "xsi";

    /**
     * Internal handle to the message factory
     */
    private MessageFactory mMessageFactory;

    /**
     * Internal handle to the logger instance
     */
    private Logger mLogger;

    /**
     * Internal handle to String Translator instance.
     */
    private StringTranslator mStringTranslator;

    /**
     * Internal handle to the transformer instance
     */
    private Transformer mTransformer;

    /**
     * Creates a new instance of MessageDenormalizerImpl.
     */
    public MessageDenormalizerImpl()
    {
        try
        {
            mLogger = Logger.getLogger(this.getClass().getPackage().getName());
            mStringTranslator = new StringTranslator(this.getClass().getPackage().getName(), this.getClass().getClassLoader());
            mMessageFactory = MessageFactory.newInstance();

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            mTransformer = transformerFactory.newTransformer();
            mTransformer.setOutputProperty("method", "xml");
            mTransformer.setOutputProperty("omit-xml-declaration", "yes");
        }
        catch (Exception exception)
        {
            // This should not happen. In case it does, log the exception and
            // set the factory object to null
	    mLogger.severe( mStringTranslator.getString("SBC_MESSAGE_FACTORY_CREATION_FAILURE") );
	    mLogger.severe( mStringTranslator.getString("SBC_ERROR_DETAILS", exception.toString()) );
            mMessageFactory = null;
            mTransformer = null;
        }
    }

    /**
     * Converts a JBI normalized message to a <code> javax.jbi.soap.SOAPMessage 
     * instance. The SOAP Header information is extracted from the NormalizedMessage
     * property "SoapHeader" and the SOAP Body content is extracted from the Normalized
     * Message content. Any attachments present in the NormalizedMessage are also
     * denormalized and added to the created <code> javax.jbi.soap.SOAPMessage  
     * instance.
     *
     * @param normalizedMessage message to be denormalized.
     * @param operation operation invoked
     * @param isResponse indicates if a response messages needs to be generated
     *
     * @return the SOAP Message.
     */
    public SOAPWrapper denormalizeMessage(
        NormalizedMessage normalizedMessage, Operation operation, boolean isResponse)
    {
        SOAPWrapper wrapper = null;
        Writer writer = null;
	mLogger.fine( mStringTranslator.getString("SBC_DENORMALIZE_JBI_MESSAGE") );

        try
        {
            // Create a SOAP Message
            ByteArrayOutputStream bufferedStream = new ByteArrayOutputStream();
            writer = new OutputStreamWriter(bufferedStream, "UTF-8");

            writeEnvelopeHeader(writer);

            if ( normalizedMessage != null)
            {
                // Writer the header to the writer instance.
                writeHeader(normalizedMessage, writer);
            }

            // Extract the body information from the Normalized Message
            writeBody(normalizedMessage, operation, isResponse, writer);
            writeEnvelopeFooter(writer);
            writer.flush();

            // Create a soap message
            SOAPMessage soapMessage = createSOAPMessage(bufferedStream);

            // Denormalize Attachments
            denormalizeAttachments ( soapMessage, normalizedMessage);
            // Create a soap response wrapper
            wrapper = new SOAPWrapper(soapMessage);

            if (normalizedMessage instanceof Fault)
            {
                wrapper.setStatus(SOAPConstants.JBI_FAULT);
            }
            else
            {
                wrapper.setStatus(SOAPConstants.JBI_SUCCESS);
            }
        }
        catch (RuntimeException runtimeException)
        {
	    mLogger.severe( mStringTranslator.getString("SBC_DENORMALIZE_JBI_MESSAGE_FAILURE_RT_EXP") );
            // Create a soap fault wrapper
            wrapper = denormalizeMessage(runtimeException);
        }
        catch (Exception exception)
        {
	    mLogger.warning( mStringTranslator.getString("SBC_DENORMALIZE_JBI_MESSAGE_FAILURE_EXP") );
	    mLogger.warning( mStringTranslator.getString("SBC_ERROR_DETAILS", exception.toString()) );
	    mLogger.warning( mStringTranslator.getString("SBC_CREATE_SOAP_FAULT") );

            // Create a soap fault wrapper
            wrapper = denormalizeMessage(exception);
        }
        finally
        {
            closeWriter(writer);
        }

	mLogger.fine( mStringTranslator.getString("SBC_SUCCESS_DENORMALIZE_JBI_MESSAGE") );

        return wrapper;
    }

    /**
     * Converts an exception to a SOAP Message. It uses the default Server fault code 
     * for denormalization.
     *
     * @param exception exception instance
     *
     * @return denormalized exception object
     */
    public SOAPWrapper denormalizeMessage(Exception exception)
    {
        return denormalizeMessage(exception, SOAPConstants.SERVER_FAULT_CODE);
    }

    /**
     * Converts an exception to a SOAP Message using the provided faultCode. The code
     * expects the faultcode passed to be part of the soap namespace.
     *
     * @param exception exception instance
     * @param faultCode fault code
     *
     * @return denormalized exception object
     */
    public SOAPWrapper denormalizeMessage(Exception exception, String faultCode)
    {
        SOAPWrapper wrapper = null;
        Writer writer = null;

	mLogger.fine( mStringTranslator.getString("SBC_DENORMALIZE_EXCEPTION") );

        try
        {
            // Create the ws-i compliant fault message from the exception
            ByteArrayOutputStream bufferedStream = new ByteArrayOutputStream();
            writer = new OutputStreamWriter(bufferedStream, "UTF-8");

            if (exception == null)
            {
		mLogger.warning( mStringTranslator.getString("SBC_NULL_OBJECT_DENORMALIZATION") );
            }

            writeEnvelopeHeader(writer);
            writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Body>");
            writeFault(exception, faultCode, writer);
            writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Body>");
            writeEnvelopeFooter(writer);
            writer.flush();

            // Create a soap message
            SOAPMessage soapMessage = createSOAPMessage(bufferedStream);

            // Create a SOAP wrapper with service url as null
            wrapper = new SOAPWrapper(soapMessage);
            wrapper.setStatus(SOAPConstants.JBI_ERROR);
        }
        catch (RuntimeException runtimeException)
        {
	    mLogger.severe( mStringTranslator.getString( "SBC_SOAP_FAULT_GENERATION_FAILURE_RT_EXP") );
        }
        catch (Exception denormalizationException)
        {
            // This should not happen. In case it does do nothing. Log message
	    mLogger.severe( mStringTranslator.getString("SBC_SOAP_FAULT_GENERATION_FAILURE") );
        }
        finally
        {
            closeWriter(writer);
        }

	mLogger.fine( mStringTranslator.getString("SBC_SUCCESS_DENORMALIZE_EXCEPTION") );

        return wrapper;
    }

    /**
     * This method extracts the payload from the Normalized Message and writes it
     * using the writer stream. The payload content is enclosed between the SOAP:Body 
     * header and SOAP:Body footer information.
     *
     * @param normalizedMessage normalized message
     * @param operation operation invoked
     * @param isResponse indicates if a response messages needs to be generated
     * @param writer writer object to be used
     *
     * @throws Exception if the body cannot be written
     */
    protected void writeBody(
        NormalizedMessage normalizedMessage, Operation operation, boolean isResponse,
        Writer writer) throws Exception
    {
        StringWriter stringWriter = null;

        try
        {
            boolean isEmptyResponse = isResponse && ( normalizedMessage == null );
            // Add the body information
            writeBodyHeader(operation, writer, isEmptyResponse);
            if ( normalizedMessage != null)
            {
                stringWriter = new StringWriter();
                Result result = new StreamResult(stringWriter);
                mTransformer.transform(normalizedMessage.getContent(), result);
                writer.write(stringWriter.toString());
            }
            writeBodyFooter(operation, writer, isEmptyResponse);
            writer.flush();
        }
        finally
        {
            closeWriter(stringWriter);
        }
    }

    /**
     * The method extracts the header information from the Normalized Message property 
     * "SoapHeader" and writes it using the writer instance. The header information
     * is expected to be propagated as a <code> javax.xml.soap.SOAPHeader  
     * implementation instance.
     *
     * @param normalizedMessage normalizedMessage
     * @param writer writer object to be used
     *
     * @throws Exception if header cannot be used to write to the writer instance
     */
    protected void writeHeader(NormalizedMessage normalizedMessage, Writer writer)
        throws Exception
    {
        // Extract header information from the Normalized Message
        SOAPHeader soapHeader =
            (SOAPHeader) normalizedMessage.getProperty(
                SOAPConstants.HEADER_PROPERTY_NAME );
        StringWriter stringWriter = null;

        if ( soapHeader != null)
        {
            try
            {
                stringWriter = new StringWriter();

                Source source = new DOMSource( soapHeader );
                Result result = new StreamResult(stringWriter);
                mTransformer.transform(source, result);

                // Add the header information
                writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Header>");
                writer.write(stringWriter.toString());
                writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Header>");
                writer.flush();
            }
            finally
            {
                closeWriter(stringWriter);
            }
        }
        else
        {
	    mLogger.fine( mStringTranslator.getString("SBC_NO_HEADER") );
        }
    }

    /**
     * Uses the writer object to write the SOAP:Body header information. This method
     * is invoked before the body payload is written.
     *
     * @param operation operation invoked
     * @param writer writer object to be used
     * @param isEmptyResponse indicates if an empty response message needs to be generated
     *
     * @throws Exception if body header cannot be written.
     */
    protected void writeBodyHeader(
        Operation operation, Writer writer, boolean isEmptyResponse)
        throws Exception
    {
        writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Body>");

        if ( isEmptyResponse)
        {
            writer.write("<" + PAYLOAD_NAMESPACE_PREFIX + ":");
            writer.write(operation.getName() + "Response");
            writer.write(" xmlns:" + PAYLOAD_NAMESPACE_PREFIX + "=\"");
            writer.write(operation.getOutputNamespace() + "\"");
            writer.write(">");
        }

        writer.flush();
    }

    /**
     * Uses writer object to write the SOAP:Body footer information. This method is
     * invoked after the body payload has been written. 
     *
     * @param operation operation invoked
     * @param writer writer object.
     * @param isEmptyResponse indicates if a response messages needs to be generated
     *
     * @throws Exception if body footer cannot be written
     */
    protected void writeBodyFooter(
        Operation operation, Writer writer, boolean isEmptyResponse)
        throws Exception
    {

        if (  isEmptyResponse )
        {
            writer.write("</" + PAYLOAD_NAMESPACE_PREFIX + ":");
            writer.write(operation.getName() + "Response>");
        }
        writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Body>");
        writer.flush();
    }

    /**
     * Uses the provided input data to create a <code> javax.xml.soap.SOAPMessage 
     * instance.
     *
     * @param byteStream Stream which contains the soap messages information as bytes.
     *
     * @return SOAP Message object
     *
     * @throws SOAPException if soap message object cannot be created.
     * @throws IOException if soap message object cannot be created.
     */
    protected SOAPMessage createSOAPMessage(ByteArrayOutputStream byteStream)
        throws SOAPException, IOException
    {
        if (mLogger.isLoggable(Level.FINEST))
        {
	    mLogger.finest( mStringTranslator.getString("SBC_DEONRMALIZED_MESSAGE_DETAILS", byteStream.toString()) );
        }

        // Create a soap message
        SOAPMessage soapMessage = mMessageFactory.createMessage();

        // Populate the fault message in the soap Message
        byte[] data = byteStream.toByteArray();
        ByteArrayInputStream soapInputStream = new ByteArrayInputStream(data);
        StreamSource streamSource = new StreamSource(soapInputStream);
        soapMessage.getSOAPPart().setContent(streamSource);
        soapInputStream.close();

        return soapMessage;
    }

    /**
     * Closes the writer instance. This method handles any exceptions thrown
     * while handling this request.
     *
     * @param writer writer instance.
     */
    protected void closeWriter(Writer writer)
    {
        if (writer != null)
        {
            try
            {
                writer.close();
            }
            catch (Exception ioException)
            {
                // This should not happen. In case it does do nothing
		mLogger.warning( mStringTranslator.getString("SBC_CLOSE_OUTPUT_STREAM") );
		mLogger.warning( mStringTranslator.getString("SBC_ERROR_DETAILS", ioException.toString()) );
            }
        }
    }

    /**
     * Uses writer object to write the SOAP:Envelope header information. This method
     * is invoked before writing the envelope content ( header and body content).
     *
     * @param writer writer object.
     *
     * @throws IOException if envelope header information cannot be written.
     */
    protected void writeEnvelopeHeader(Writer writer) throws IOException
    {
        // Write the soap envelope
        writer.write(
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<" + SOAP_NAMESPACE_PREFIX +
            ":Envelope xmlns:" + SOAP_NAMESPACE_PREFIX +
            "=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:" +
            XML_SCHEMA_INSTANCE_NAMESPACE_PREFIX +
            "=\"http://www.w3.org/2001/XMLSchema-instance\">");
        writer.flush();
    }

    /**
     * Uses writer object to write the SOAP:Envelope footer information. This method
     * is invoked after writing the envelope content ( header and body content).
     *
     * @param writer writer object
     *
     * @throws IOException if envelope footer information cannot be written.
     */
    protected void writeEnvelopeFooter(Writer writer) throws IOException
    {
        writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Envelope>");
        writer.flush();
    }

    /**
     * Create the SOAP:Fault message based on the provided exception details and writes
     * it using the writer instance.
     *
     * @param exception  exception thrown
     * @param faultCode fault code
     * @param writer writer object
     *
     * @throws IOException if fault message cannot be generated.
     */
    protected void writeFault(Exception exception, String faultCode, Writer writer)
        throws IOException
    {
        writer.write(
            "<" + SOAP_NAMESPACE_PREFIX + ":Fault>" + SOAP_NAMESPACE_PREFIX +
            ":" + faultCode + "</faultcode>");

        if (exception != null)
        {
            writer.write("<faultstring>" +
                         sanitizeMessage(exception.getMessage()) + "</faultstring>");
        }

        writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Fault>");
        writer.flush();
    }

    /**
     * Converts a JBI Fault mesage to a standard <code> javax.xml.soap.SOAPMessage 
     * message instance. It uses the default Server fault code for denormalization.
     *
     * @param faultMessage JBI fault message.
     *
     * @return a new SOAPWrapper instance which contains the SOAP fault Message.
     */
    public SOAPWrapper denormalizeFaultMessage(Fault faultMessage)
    {
        return denormalizeFaultMessage(faultMessage, SOAPConstants.SERVER_FAULT_CODE);
    }

    /**
     * Converts a JBI Fault mesage to a SOAP Message using the specified fault code.
     *
     * @param faultMessage JBI fault message.
     * @param faultCode fault code to be used in the fault message
     *
     * @return a new SOAPWrapper instance which contains the SOAP fault Message.
     */
    public SOAPWrapper denormalizeFaultMessage(Fault faultMessage, String faultCode)
    {
        SOAPWrapper wrapper = null;
        Writer writer = null;

	mLogger.fine( mStringTranslator.getString("SBC_DENORMALIZE_FAULT_MESSAGE") );

        try
        {
            // Create the ws-i compliant fault message from the exception
            ByteArrayOutputStream bufferedStream = new ByteArrayOutputStream();
            String messageFaultCode = (String) faultMessage.getProperty(
                                        SOAPConstants.FAULT_CODE_PROPERTY_NAME);
            String faultString = (String) faultMessage.getProperty(
                                        SOAPConstants.FAULT_STRING_PROPERTY_NAME);

            if ( messageFaultCode != null )
            {
                // Override the fault code with the message fault code.
                faultCode = messageFaultCode;
            }

            if ( faultString == null )
            {
                faultString = mStringTranslator.getString("SBC_DEFAULT_FAULT_STRING");
            }
            writer = new OutputStreamWriter(bufferedStream, "UTF-8");
            writeEnvelopeHeader(writer);
            writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Body>");
            writer.write(
                "<" + SOAP_NAMESPACE_PREFIX + ":Fault " +
                XML_SCHEMA_INSTANCE_NAMESPACE_PREFIX + ":type=\"" +
                SOAP_NAMESPACE_PREFIX + ":Fault\"" + "><faultcode>" +
                SOAP_NAMESPACE_PREFIX + ":" + faultCode + "</faultcode>");
            writer.write("<faultstring>" + faultString + "");
            writeFaultDetail(faultMessage, writer);
            writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Fault>");
            writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Body>");
            writeEnvelopeFooter(writer);
            writer.flush();

            // Create a soap message
            SOAPMessage soapMessage = createSOAPMessage(bufferedStream);

            // Create a SOAP wrapper with service url as null
            wrapper = new SOAPWrapper(soapMessage);
            wrapper.setStatus(SOAPConstants.JBI_FAULT);
        }
        catch (RuntimeException runtimeException)
        {
	    mLogger.severe( mStringTranslator.getString( "SBC_SOAP_FAULT_GENERATION_FAILURE_RT_EXP") );
        }
        catch (Exception exception)
        {
            // This should not happen. In case it does do nothing. Log message
	    mLogger.severe( mStringTranslator.getString("SBC_SOAP_FAULT_GENERATION_FAILURE") );
        }
        finally
        {
            closeWriter(writer);
        }

	mLogger.fine( mStringTranslator.getString("SBC_SUCCESS_DENORMALIZE_FAULT") );

        return wrapper;
    }

    /**
     * Writes the detailed fault message using the provided writer instance.
     *
     * @param faultMessage JBI Fault object which contains the fault details.
     * @param writer writer object to be used.
     *
     * @throws Exception if the fault detail vould not be written.
     */
    private void writeFaultDetail(Fault faultMessage, Writer writer)
        throws Exception
    {
        StringWriter stringWriter = null;

        try
        {
            stringWriter = new StringWriter();

            Result result = new StreamResult(stringWriter);
            mTransformer.transform(faultMessage.getContent(), result);

            // Add the fault detail
            String detailString = stringWriter.toString().trim();

            if (!detailString.equals(""))
            {
                writer.write("<detail>");
                writer.write(detailString);
                writer.write("</detail>");
                writer.flush();
            }
        }
        finally
        {
            closeWriter(stringWriter);
        }
    }

    /**
     * Sanitizes the messages so that it can be properly read by an XML parser.
     *
     * @param errorMessage error message to be sanitized.
     *
     * @return sanitized error message.
     */
    protected String sanitizeMessage(String errorMessage)
    {
        StringBuffer sanitizedBuffer = new StringBuffer();

        for (int i = 0; (errorMessage != null) && (i < errorMessage.length()); i++)
        {
            char currentChar = errorMessage.charAt(i);

            switch (currentChar)
            {
            case '"':
                sanitizedBuffer.append(""");

                break;

            case '&':
                sanitizedBuffer.append("&");

                break;

            case '<':
                sanitizedBuffer.append("<");

                break;

            case '>':
                sanitizedBuffer.append(">");

                break;

            default:
                sanitizedBuffer.append(currentChar);
            }
        }

        if (errorMessage == null)
        {
            return "INTERNAL SERVER ERROR";
        }
        else
        {
            return sanitizedBuffer.toString();
        }
    }

    /**
     * Denormalizes the attachments present in the JBI Normalized Message and adds
     * them to the <code> javax.xml.soap.SoapMessage  instance.
     *
     * @param soapMessage soap message.
     * @param normalizedMessage  normalized message instance.
     */
    private void denormalizeAttachments ( SOAPMessage soapMessage,
                                          NormalizedMessage normalizedMessage)
    {
        if ( normalizedMessage != null )
        {
            Iterator attachmentIter = normalizedMessage.getAttachmentNames().iterator();
            for (; attachmentIter.hasNext();)
            {
                String attachmentIdentifier = (String) attachmentIter.next();
                DataHandler dataHandler =
                            normalizedMessage.getAttachment( attachmentIdentifier);
                AttachmentPart attachment =
                    soapMessage.createAttachmentPart( dataHandler);
                attachment.setContentId ( attachmentIdentifier);
                attachment.setContentType ( dataHandler.getContentType());
                soapMessage.addAttachmentPart ( attachment );
            }
        }
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish MessageDenormalizerImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.