CustomHTMLTagProcessor for iTextSharp - base64

I have the following code;
Dim sr As StreamReader = New StreamReader("C:\\temp\\test.htm")
Dim line As String
line = sr.ReadToEnd
sr.Close()
Dim fsNew As New StringReader(line)
Dim Document As New Document()
Using fs As New FileStream("C:\\temp\\test.pdf", FileMode.Create)
PdfWriter.GetInstance(Document, fs)
Using stringReader As New StringReader(line)
Dim parsedList As List(Of IElement) = HTMLWorker.ParseToList(stringReader, Nothing)
Document.Open()
For Each item As Object In parsedList
Document.Add(DirectCast(item, IElement))
Next
Document.Close()
End Using
End Using
Document.Close()
I am trying to fix the problem with embedded base64 images that is referenced here. I created the CustomImageHTMLTagProcessor which is using the IHTMLTagProcessor interface, but when it came time to modify the HTMLWorker class, I wasn't sure what to change. This is the HTMLWorker class.
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Globalization;
using System.util;
using iTextSharp.text;
using iTextSharp.text.log;
using iTextSharp.text.html;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.draw;
using iTextSharp.text.xml.simpleparser;
namespace iTextSharp.text.html.simpleparser {
[Obsolete]
public class HTMLWorker : ISimpleXMLDocHandler, IDocListener {
private static readonly ILogger LOGGER = LoggerFactory.GetLogger(typeof(HTMLWorker));
protected IDocListener document;
protected internal IDictionary<String, IHTMLTagProcessor> tags;
public HTMLWorker(IDocListener document) : this(document, null, null) {
}
public HTMLWorker(IDocListener document, IDictionary<String, IHTMLTagProcessor> tags, StyleSheet style) {
this.document = document;
SetSupportedTags(tags);
SetStyleSheet(style);
}
virtual public void SetSupportedTags(IDictionary<String, IHTMLTagProcessor> tags) {
if (tags == null)
tags = new HTMLTagProcessors();
this.tags = tags;
}
virtual public void SetStyleSheet(StyleSheet style) {
if (style == null)
style = new StyleSheet();
this.style = style;
}
virtual public void Parse(TextReader reader) {
LOGGER.Info("Please note, there is a more extended version of the HTMLWorker available in the iText XMLWorker");
SimpleXMLParser.Parse(this, null, reader, true);
}
// state machine
protected Stack<IElement> stack = new Stack<IElement>();
protected Paragraph currentParagraph;
private ChainedProperties chain = new ChainedProperties();
public virtual void StartDocument() {
Dictionary<String, String> attrs = new Dictionary<String, String>();
style.ApplyStyle(HtmlTags.BODY, attrs);
chain.AddToChain(HtmlTags.BODY, attrs);
}
public virtual void StartElement(String tag, IDictionary<String, String> attrs) {
IHTMLTagProcessor htmlTag;
tags.TryGetValue(tag, out htmlTag);
if (htmlTag == null) {
return;
}
style.ApplyStyle(tag, attrs);
StyleSheet.ResolveStyleAttribute(attrs, chain);
htmlTag.StartElement(this, tag, attrs);
}
public virtual void Text(String content) {
if (skipText)
return;
if (currentParagraph == null) {
currentParagraph = CreateParagraph();
}
if (!insidePRE) {
// newlines and carriage returns are ignored
if (content.Trim().Length == 0 && content.IndexOf(' ') < 0) {
return;
}
content = HtmlUtilities.EliminateWhiteSpace(content);
}
Chunk chunk = CreateChunk(content);
currentParagraph.Add(chunk);
}
public virtual void EndElement(String tag) {
IHTMLTagProcessor htmlTag;
tags.TryGetValue(tag, out htmlTag);
if (htmlTag == null) {
return;
}
// process the tag
htmlTag.EndElement(this, tag);
}
public virtual void EndDocument() {
// flush the stack
foreach (IElement e in stack)
document.Add(e);
// add current paragraph
if (currentParagraph != null)
document.Add(currentParagraph);
currentParagraph = null;
}
virtual public void NewLine() {
if (currentParagraph == null) {
currentParagraph = new Paragraph();
}
currentParagraph.Add(CreateChunk("\n"));
}
virtual public void CarriageReturn() {
if (currentParagraph == null)
return;
if (stack.Count == 0)
document.Add(currentParagraph);
else {
IElement obj = stack.Pop();
if (obj is ITextElementArray) {
ITextElementArray current = (ITextElementArray) obj;
current.Add(currentParagraph);
}
stack.Push(obj);
}
currentParagraph = null;
}
/**
* Stacks the current paragraph, indicating that we're starting
* a new span.
* #since 5.0.6
*/
virtual public void FlushContent() {
PushToStack(currentParagraph);
currentParagraph = new Paragraph();
}
/**
* Pushes an element to the Stack.
* #param element
* #since 5.0.6
*/
virtual public void PushToStack(IElement element) {
if (element != null)
stack.Push(element);
}
/**
* Updates the chain with a new tag and new attributes.
* #param tag the new tag
* #param attrs the corresponding attributes
* #since 5.0.6
*/
virtual public void UpdateChain(String tag, IDictionary<String, String> attrs) {
chain.AddToChain(tag, attrs);
}
/**
* Updates the chain by removing a tag.
* #param tag the new tag
* #since 5.0.6
*/
virtual public void UpdateChain(String tag) {
chain.RemoveChain(tag);
}
// providers that help find resources such as images and fonts
/**
* Key used to store the image provider in the providers map.
* #since 5.0.6
*/
public const String IMG_PROVIDER = "img_provider";
/**
* Key used to store the image processor in the providers map.
* #since 5.0.6
*/
public const String IMG_PROCESSOR = "img_interface";
/**
* Key used to store the image store in the providers map.
* #since 5.0.6
*/
public const String IMG_STORE = "img_static";
/**
* Key used to store the image baseurl provider in the providers map.
* #since 5.0.6
*/
public const String IMG_BASEURL = "img_baseurl";
/**
* Key used to store the font provider in the providers map.
* #since 5.0.6
*/
public const String FONT_PROVIDER = "font_factory";
/**
* Key used to store the link provider in the providers map.
* #since 5.0.6
*/
public const String LINK_PROVIDER = "alink_interface";
/**
* IDictionary containing providers such as a FontProvider or ImageProvider.
* #since 5.0.6 (renamed from interfaceProps)
*/
private IDictionary<String, Object> providers = new Dictionary<String, Object>();
/**
* Setter for the providers.
* If a FontProvider is added, the ElementFactory is updated.
* #param providers a IDictionary with different providers
* #since 5.0.6
*/
virtual public void SetProviders(IDictionary<String, Object> providers) {
if (providers == null)
return;
this.providers = providers;
IFontProvider ff = null;
if (providers.ContainsKey(FONT_PROVIDER))
ff = (IFontProvider)providers[FONT_PROVIDER];
if (ff != null)
factory.FontProvider = ff;
}
// factory that helps create objects
/**
* Factory that is able to create iText Element objects.
* #since 5.0.6
*/
private ElementFactory factory = new ElementFactory();
/**
* Creates a Chunk using the factory.
* #param content the content of the chunk
* #return a Chunk with content
* #since 5.0.6
*/
virtual public Chunk CreateChunk(String content) {
return factory.CreateChunk(content, chain);
}
/**
* Creates a Paragraph using the factory.
* #return a Paragraph without any content
* #since 5.0.6
*/
virtual public Paragraph CreateParagraph() {
return factory.CreateParagraph(chain);
}
/**
* Creates a List object.
* #param tag should be "ol" or "ul"
* #return a List object
* #since 5.0.6
*/
virtual public List CreateList(String tag) {
return factory.CreateList(tag, chain);
}
/**
* Creates a ListItem object.
* #return a ListItem object
* #since 5.0.6
*/
virtual public ListItem CreateListItem() {
return factory.CreateListItem(chain);
}
/**
* Creates a LineSeparator object.
* #param attrs properties of the LineSeparator
* #return a LineSeparator object
* #since 5.0.6
*/
virtual public LineSeparator CreateLineSeparator(IDictionary<String, String> attrs) {
return factory.CreateLineSeparator(attrs, currentParagraph.Leading / 2);
}
/**
* Creates an Image object.
* #param attrs properties of the Image
* #return an Image object (or null if the Image couldn't be found)
* #throws DocumentException
* #throws IOException
* #since 5.0.6
*/
virtual public Image CreateImage(IDictionary<String, String> attrs) {
String src;
attrs.TryGetValue(HtmlTags.SRC, out src);
if (src == null)
return null;
Image img = factory.CreateImage(
src, attrs, chain, document,
providers.ContainsKey(IMG_PROVIDER) ? (IImageProvider)providers[IMG_PROVIDER] : null,
providers.ContainsKey(IMG_STORE) ? (ImageStore)providers[IMG_STORE] : null,
providers.ContainsKey(IMG_BASEURL) ? (string)providers[IMG_BASEURL] : null);
return img;
}
/**
* Creates a Cell.
* #param tag the tag
* #return a CellWrapper object
* #since 5.0.6
*/
virtual public CellWrapper CreateCell(String tag) {
return new CellWrapper(tag, chain);
}
// processing objects
/**
* Adds a link to the current paragraph.
* #since 5.0.6
*/
virtual public void ProcessLink() {
if (currentParagraph == null) {
currentParagraph = new Paragraph();
}
// The link provider allows you to do additional processing
ILinkProcessor i = null;
if (providers.ContainsKey(LINK_PROVIDER))
i = (ILinkProcessor) providers[LINK_PROVIDER];
if (i == null || !i.Process(currentParagraph, chain)) {
// sets an Anchor for all the Chunks in the current paragraph
String href = chain[HtmlTags.HREF];
if (href != null) {
foreach (Chunk ck in currentParagraph.Chunks) {
ck.SetAnchor(href);
}
}
}
// a link should be added to the current paragraph as a phrase
if (stack.Count == 0) {
// no paragraph to add too, 'a' tag is first element
Paragraph tmp = new Paragraph(new Phrase(currentParagraph));
currentParagraph = tmp;
} else {
Paragraph tmp = (Paragraph) stack.Pop();
tmp.Add(new Phrase(currentParagraph));
currentParagraph = tmp;
}
}
/**
* Fetches the List from the Stack and adds it to
* the TextElementArray on top of the Stack,
* or to the Document if the Stack is empty.
* #throws DocumentException
* #since 5.0.6
*/
virtual public void ProcessList() {
if (stack.Count == 0)
return;
IElement obj = stack.Pop();
if (!(obj is List)) {
stack.Push(obj);
return;
}
if (stack.Count == 0)
document.Add(obj);
else
((ITextElementArray) stack.Peek()).Add(obj);
}
/**
* Looks for the List object on the Stack,
* and adds the ListItem to the List.
* #throws DocumentException
* #since 5.0.6
*/
virtual public void ProcessListItem() {
if (stack.Count == 0)
return;
IElement obj = stack.Pop();
if (!(obj is ListItem)) {
stack.Push(obj);
return;
}
if (stack.Count == 0) {
document.Add(obj);
return;
}
ListItem item = (ListItem) obj;
IElement list = stack.Pop();
if (!(list is List)) {
stack.Push(list);
return;
}
((List) list).Add(item);
item.AdjustListSymbolFont();
stack.Push(list);
}
/**
* Processes an Image.
* #param img
* #param attrs
* #throws DocumentException
* #since 5.0.6
*/
virtual public void ProcessImage(Image img, IDictionary<String, String> attrs) {
IImageProcessor processor = null;
if (providers.ContainsKey(IMG_PROCESSOR))
processor = (IImageProcessor)providers[IMG_PROCESSOR];
if (processor == null || !processor.Process(img, attrs, chain, document)) {
String align;
attrs.TryGetValue(HtmlTags.ALIGN, out align);
if (align != null) {
CarriageReturn();
}
if (currentParagraph == null) {
currentParagraph = CreateParagraph();
}
currentParagraph.Add(new Chunk(img, 0, 0, true));
currentParagraph.Alignment = HtmlUtilities.AlignmentValue(align);
if (align != null) {
CarriageReturn();
}
}
}
/**
* Processes the Table.
* #throws DocumentException
* #since 5.0.6
*/
virtual public void ProcessTable() {
TableWrapper table = (TableWrapper) stack.Pop();
PdfPTable tb = table.CreateTable();
tb.SplitRows = true;
if (stack.Count == 0)
document.Add(tb);
else
((ITextElementArray) stack.Peek()).Add(tb);
}
/**
* Gets the TableWrapper from the Stack and adds a new row.
* #since 5.0.6
*/
virtual public void ProcessRow() {
List<PdfPCell> row = new List<PdfPCell>();
List<float> cellWidths = new List<float>();
bool percentage = false;
float width;
float totalWidth = 0;
int zeroWidth = 0;
TableWrapper table = null;
while (true) {
IElement obj = stack.Pop();
if (obj is CellWrapper) {
CellWrapper cell = (CellWrapper)obj;
width = cell.Width;
cellWidths.Add(width);
percentage |= cell.IsPercentage;
if (width == 0) {
zeroWidth++;
}
else {
totalWidth += width;
}
row.Add(cell.Cell);
}
if (obj is TableWrapper) {
table = (TableWrapper) obj;
break;
}
}
table.AddRow(row);
if (cellWidths.Count > 0) {
// cells come off the stack in reverse, naturally
totalWidth = 100 - totalWidth;
cellWidths.Reverse();
float[] widths = new float[cellWidths.Count];
bool hasZero = false;
for (int i = 0; i < widths.Length; i++) {
widths[i] = cellWidths[i];
if (widths[i] == 0 && percentage && zeroWidth > 0) {
widths[i] = totalWidth / zeroWidth;
}
if (widths[i] == 0) {
hasZero = true;
break;
}
}
if (!hasZero)
table.ColWidths = widths;
}
stack.Push(table);
}
// state variables and methods
/** Stack to keep track of table tags. */
private Stack<bool[]> tableState = new Stack<bool[]>();
/** Boolean to keep track of TR tags. */
private bool pendingTR = false;
/** Boolean to keep track of TD and TH tags */
private bool pendingTD = false;
/** Boolean to keep track of LI tags */
private bool pendingLI = false;
/**
* Boolean to keep track of PRE tags
* #since 5.0.6 renamed from isPRE
*/
private bool insidePRE = false;
/**
* Indicates if text needs to be skipped.
* #since iText 5.0.6 (private => protected)
*/
protected internal bool skipText = false;
/**
* Pushes the values of pendingTR and pendingTD
* to a state stack.
* #since 5.0.6
*/
virtual public void PushTableState() {
tableState.Push(new bool[] { pendingTR, pendingTD });
}
/**
* Pops the values of pendingTR and pendingTD
* from a state stack.
* #since 5.0.6
*/
virtual public void PopTableState() {
bool[] state = tableState.Pop();
pendingTR = state[0];
pendingTD = state[1];
}
/**
* #return the pendingTR
* #since 5.0.6
*/
virtual public bool IsPendingTR() {
return pendingTR;
}
/**
* #param pendingTR the pendingTR to set
* #since 5.0.6
*/
virtual public void SetPendingTR(bool pendingTR) {
this.pendingTR = pendingTR;
}
/**
* #return the pendingTD
* #since 5.0.6
*/
virtual public bool IsPendingTD() {
return pendingTD;
}
/**
* #param pendingTD the pendingTD to set
* #since 5.0.6
*/
virtual public void SetPendingTD(bool pendingTD) {
this.pendingTD = pendingTD;
}
/**
* #return the pendingLI
* #since 5.0.6
*/
virtual public bool IsPendingLI() {
return pendingLI;
}
/**
* #param pendingLI the pendingLI to set
* #since 5.0.6
*/
virtual public void SetPendingLI(bool pendingLI) {
this.pendingLI = pendingLI;
}
/**
* #return the insidePRE
* #since 5.0.6
*/
virtual public bool IsInsidePRE() {
return insidePRE;
}
/**
* #param insidePRE the insidePRE to set
* #since 5.0.6
*/
virtual public void SetInsidePRE(bool insidePRE) {
this.insidePRE = insidePRE;
}
/**
* #return the skipText
* #since 5.0.6
*/
virtual public bool IsSkipText() {
return skipText;
}
/**
* #param skipText the skipText to set
* #since 5.0.6
*/
virtual public void SetSkipText(bool skipText) {
this.skipText = skipText;
}
// static methods to parse HTML to a List of Element objects.
/** The resulting list of elements. */
protected List<IElement> objectList;
/**
* Parses an HTML source to a List of Element objects
* #param reader the HTML source
* #param style a StyleSheet object
* #return a List of Element objects
* #throws IOException
*/
public static List<IElement> ParseToList(TextReader reader, StyleSheet style) {
return ParseToList(reader, style, null);
}
/**
* Parses an HTML source to a List of Element objects
* #param reader the HTML source
* #param style a StyleSheet object
* #param providers map containing classes with extra info
* #return a List of Element objects
* #throws IOException
*/
public static List<IElement> ParseToList(TextReader reader, StyleSheet style,
Dictionary<String, Object> providers) {
return ParseToList(reader, style, null, providers);
}
/**
* Parses an HTML source to a List of Element objects
* #param reader the HTML source
* #param style a StyleSheet object
* #param tags a map containing supported tags and their processors
* #param providers map containing classes with extra info
* #return a List of Element objects
* #throws IOException
* #since 5.0.6
*/
public static List<IElement> ParseToList(TextReader reader, StyleSheet style,
IDictionary<String, IHTMLTagProcessor> tags, Dictionary<String, Object> providers) {
HTMLWorker worker = new HTMLWorker(null, tags, style);
worker.document = worker;
worker.SetProviders(providers);
worker.objectList = new List<IElement>();
worker.Parse(reader);
return worker.objectList;
}
// DocListener interface
/**
* #see com.itextpdf.text.ElementListener#add(com.itextpdf.text.Element)
*/
virtual public bool Add(IElement element) {
objectList.Add(element);
return true;
}
/**
* #see com.itextpdf.text.DocListener#close()
*/
virtual public void Close() {
}
/**
* #see com.itextpdf.text.DocListener#newPage()
*/
virtual public bool NewPage() {
return true;
}
/**
* #see com.itextpdf.text.DocListener#open()
*/
virtual public void Open() {
}
/**
* #see com.itextpdf.text.DocListener#resetPageCount()
*/
virtual public void ResetPageCount() {
}
/**
* #see com.itextpdf.text.DocListener#setMarginMirroring(bool)
*/
virtual public bool SetMarginMirroring(bool marginMirroring) {
return false;
}
/**
* #see com.itextpdf.text.DocListener#setMarginMirroring(bool)
* #since 2.1.6
*/
virtual public bool SetMarginMirroringTopBottom(bool marginMirroring) {
return false;
}
/**
* #see com.itextpdf.text.DocListener#setMargins(float, float, float, float)
*/
virtual public bool SetMargins(float marginLeft, float marginRight,
float marginTop, float marginBottom) {
return true;
}
/**
* #see com.itextpdf.text.DocListener#setPageCount(int)
*/
virtual public int PageCount {
set {
}
}
/**
* #see com.itextpdf.text.DocListener#setPageSize(com.itextpdf.text.Rectangle)
*/
virtual public bool SetPageSize(Rectangle pageSize) {
return true;
}
// deprecated methods
/**
* Sets the providers.
* #deprecated use SetProviders() instead
*/
virtual public void SetInterfaceProps(Dictionary<String, Object> providers) {
SetProviders(providers);
}
/**
* Gets the providers
* #deprecated use GetProviders() instead
*/
virtual public IDictionary<String, Object> GetInterfaceProps() {
return providers;
}
public virtual void Dispose() {
Close();
}
}
}

As Chris Haas Mentioned HtmlWorker is Deprecated. XmlWorker is the new way to convert HTML to PDF.

Related

Using Carbon diffForHumans in my model in laravel 8

I am using laravel 8 framework as my backend for my android application and I want to output time the same way instagram shows time but each time I use carbon diffForHumans it shows 2hours from now and I want it to show 1 minute ago, just now, 2 weeks ago,2 hours ago.
here is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Carbon\Carbon;
class News extends Model
{
use HasFactory;
protected $table = "news";
protected $fillable = [
'title',
'image',
'body'
];
protected $casts = [
'created_at' => 'datetime:d-m-Y',
'updated_at' => 'datetime:d-m-Y'
];
protected $appends=['published'];
public function getPublishedAttribute(){
return Carbon::createFromTimeStamp(strtotime($this->attributes['created_at']) )->diffForHumans();
}
}
here is my controller
<?php
namespace App\Http\Controllers;
use App\News;
use Illuminate\Http\Request;
class NewsController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$allposts = News:://get()->sortByDesc(function($query){
// return $query->toArray(['id']);
//})->
all();
return response()->json(['newsitemlist' => $allposts], 200);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$allposts = News::find($id);
if (is_null($allposts)) {
return response()->json(['message' => "News not available"], 404);
}
return response()->json(['newsitemlist' => $allposts], 200);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$allposts = News::find($id);
if (is_null($allposts)) {
return response()->json(['message' => "News not available"], 404);
}
$allposts->delete();
return response()->json(['message' => "News Deleted Succesfully"], 200);
}
}
You can also use
public function getCreatedAtAttribute($value){
return Carbon::parse($value)->diffForHumans();
}
Based on Docs, this is what you need to do to modify created_at value. Its called Accessor
public function getCreatedAtAttribute($value){
return Carbon::createFromFormat('Y-m-d H:i:s', $value)->diffForHumans();
}
Also you can check more about Carbon API here

parse json and get attributes with rest controller java

I have this code, the entity is persistable I want to make it non persistable so I parse json file and get name and icon values and display them instead of getting this values from database so that is why I want to change this code
/**
* A Pcomponent.
*/
#Entity
#Table(name = "pcomponent")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Pcomponent implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "icon")
private String icon;
#Column(name = "name")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getIcon() {
return icon;
}
public Pcomponent icon(String icon) {
this.icon = icon;
return this;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public Pcomponent name(String name) {
this.name = name;
return this;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Pcomponent pcomponent = (Pcomponent) o;
if (pcomponent.id == null || id == null) {
return false;
}
return Objects.equals(id, pcomponent.id);
}
#Override
public int hashCode() {
return Objects.hashCode(id);
}
#Override
public String toString() {
return "Pcomponent{" +
"id=" + id +
", icon='" + icon + "'" +
", name='" + name + "'" +
'}';
}
}
/**
* Spring Data JPA repository for the Pcomponent entity.
*/
public interface PcomponentRepository extends
JpaRepository<Pcomponent,Long> {
}
/**
* A DTO for the Pcomponent entity.
*/
public class PcomponentDTO implements Serializable {
private Long id;
private String icon;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PcomponentDTO pcomponentDTO = (PcomponentDTO) o;
if ( ! Objects.equals(id, pcomponentDTO.id)) {
return false;
}
return true;
}
#Override
public int hashCode() {
return Objects.hashCode(id);
}
#Override
public String toString() {
return "PcomponentDTO{" +
"id=" + id +
", icon='" + icon + "'" +
", name='" + name + "'" +
'}';
}
}
/**
* Mapper for the entity Pcomponent and its DTO PcomponentDTO.
*/
#Mapper(componentModel = "spring", uses = {})
public interface PcomponentMapper {
PcomponentDTO pcomponentToPcomponentDTO(Pcomponent pcomponent);
List<PcomponentDTO> pcomponentsToPcomponentDTOs(List<Pcomponent> pcomponents);
Pcomponent pcomponentDTOToPcomponent(PcomponentDTO pcomponentDTO);
List<Pcomponent> pcomponentDTOsToPcomponents(List<PcomponentDTO> pcomponentDTOs);
/**
* generating the fromId for all mappers if the databaseType is sql, as the class has relationship to it might need it, instead of
* creating a new attribute to know if the entity has any relationship from some other entity
*
* #param id id of the entity
* #return the entity instance
*/
default Pcomponent pcomponentFromId(Long id) {
if (id == null) {
return null;
}
Pcomponent pcomponent = new Pcomponent();
pcomponent.setId(id);
return pcomponent;
}
}
/**
* Service Implementation for managing Pcomponent.
*/
#Service
#Transactional
public class PcomponentService {
private final Logger log =
LoggerFactory.getLogger(PcomponentService.class);
private final PcomponentRepository pcomponentRepository;
private final PcomponentMapper pcomponentMapper;
public PcomponentService(PcomponentRepository pcomponentRepository, PcomponentMapper pcomponentMapper) {
this.pcomponentRepository = pcomponentRepository;
this.pcomponentMapper = pcomponentMapper;
}
/**
* Save a pcomponent.
*
* #param pcomponentDTO the entity to save
* #return the persisted entity
*/
public PcomponentDTO save(PcomponentDTO pcomponentDTO) {
log.debug("Request to save Pcomponent : {}", pcomponentDTO);
Pcomponent pcomponent = pcomponentMapper.pcomponentDTOToPcomponent(pcomponentDTO);
pcomponent = pcomponentRepository.save(pcomponent);
PcomponentDTO result = pcomponentMapper.pcomponentToPcomponentDTO(pcomponent);
return result;
}
/**
* Get all the pcomponents.
*
* #param pageable the pagination information
* #return the list of entities
*/
#Transactional(readOnly = true)
public Page<PcomponentDTO> findAll(Pageable pageable) {
log.debug("Request to get all Pcomponents");
Page<Pcomponent> result = pcomponentRepository.findAll(pageable);
return result.map(pcomponent -> pcomponentMapper.pcomponentToPcomponentDTO(pcomponent));
}
/**
* Get one pcomponent by id.
*
* #param id the id of the entity
* #return the entity
*/
#Transactional(readOnly = true)
public PcomponentDTO findOne(Long id) {
log.debug("Request to get Pcomponent : {}", id);
Pcomponent pcomponent = pcomponentRepository.findOne(id);
PcomponentDTO pcomponentDTO = pcomponentMapper.pcomponentToPcomponentDTO(pcomponent);
return pcomponentDTO;
}
/**
* Delete the pcomponent by id.
*
* #param id the id of the entity
*/
public void delete(Long id) {
log.debug("Request to delete Pcomponent : {}", id);
pcomponentRepository.delete(id);
}
}
/**
* REST controller for managing Pcomponent.
*/
#RestController
#RequestMapping("/api")
public class PcomponentResource {
private final Logger log =
LoggerFactory.getLogger(PcomponentResource.class);
private static final String ENTITY_NAME = "pcomponent";
private final PcomponentService pcomponentService;
public PcomponentResource(PcomponentService pcomponentService) {
this.pcomponentService = pcomponentService;
}
/**
* POST /pcomponents : Create a new pcomponent.
*
* #param pcomponentDTO the pcomponentDTO to create
* #return the ResponseEntity with status 201 (Created) and with body the new pcomponentDTO, or with status 400 (Bad Request) if the pcomponent has already an ID
* #throws URISyntaxException if the Location URI syntax is incorrect
*/
#PostMapping("/pcomponents")
#Timed
public ResponseEntity<PcomponentDTO> createPcomponent(#RequestBody PcomponentDTO pcomponentDTO) throws URISyntaxException {
log.debug("REST request to save Pcomponent : {}", pcomponentDTO);
if (pcomponentDTO.getId() != null) {
return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "idexists", "A new pcomponent cannot already have an ID")).body(null);
}
PcomponentDTO result = pcomponentService.save(pcomponentDTO);
return ResponseEntity.created(new URI("/api/pcomponents/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
.body(result);
}
/**
* PUT /pcomponents : Updates an existing pcomponent.
*
* #param pcomponentDTO the pcomponentDTO to update
* #return the ResponseEntity with status 200 (OK) and with body the updated pcomponentDTO,
* or with status 400 (Bad Request) if the pcomponentDTO is not valid,
* or with status 500 (Internal Server Error) if the pcomponentDTO couldnt be updated
* #throws URISyntaxException if the Location URI syntax is incorrect
*/
#PutMapping("/pcomponents")
#Timed
public ResponseEntity<PcomponentDTO> updatePcomponent(#RequestBody PcomponentDTO pcomponentDTO) throws URISyntaxException {
log.debug("REST request to update Pcomponent : {}", pcomponentDTO);
if (pcomponentDTO.getId() == null) {
return createPcomponent(pcomponentDTO);
}
PcomponentDTO result = pcomponentService.save(pcomponentDTO);
return ResponseEntity.ok()
.headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, pcomponentDTO.getId().toString()))
.body(result);
}
/**
* GET /pcomponents : get all the pcomponents.
*
* #param pageable the pagination information
* #return the ResponseEntity with status 200 (OK) and the list of pcomponents in body
*/
#GetMapping("/pcomponents")
#Timed
public ResponseEntity<List<PcomponentDTO>> getAllPcomponents(#ApiParam Pageable pageable) {
log.debug("REST request to get a page of Pcomponents");
Page<PcomponentDTO> page = pcomponentService.findAll(pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/pcomponents");
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
}
/**
* GET /pcomponents/:id : get the "id" pcomponent.
*
* #param id the id of the pcomponentDTO to retrieve
* #return the ResponseEntity with status 200 (OK) and with body the pcomponentDTO, or with status 404 (Not Found)
*/
#GetMapping("/pcomponents/{id}")
#Timed
public ResponseEntity<PcomponentDTO> getPcomponent(#PathVariable Long id) {
log.debug("REST request to get Pcomponent : {}", id);
PcomponentDTO pcomponentDTO = pcomponentService.findOne(id);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(pcomponentDTO));
}
/**
* DELETE /pcomponents/:id : delete the "id" pcomponent.
*
* #param id the id of the pcomponentDTO to delete
* #return the ResponseEntity with status 200 (OK)
*/
#DeleteMapping("/pcomponents/{id}")
#Timed
public ResponseEntity<Void> deletePcomponent(#PathVariable Long id) {
log.debug("REST request to delete Pcomponent : {}", id);
pcomponentService.delete(id);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
}
}

Twig Relationship with extra columns

I have a problem and don't know the best practice to solve it.
I want to have a form for my core data. The core data is all versionable.
I solved it with a GUID, to know the togetherness of the versions.
So now I have two versionable entities AgeClass and HighscoreList that can have a many-to-many relationship. The relationship has to be versionable, too, so I created a ReferenceEntity RefAgeClassHighscoreList. Now I have relationships with extra columns
valid-from [and]
valid-to
But now I don't know how I should build my form.
When I edit an AgeClass, all current (valid) HighscoreList items should be show as a checkbox.
But when I build the edit form, the values must be bound with a RefAgeClassHighscoreList entity.
I hope you understand my problem.
AgeClass:
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\DSV\Core\BaseDSVCoreDataRepository")
* */
class AgeClass extends BaseDSVCoreData
{
/**
* #ORM\Column(type="integer")
* #NotBlank()
* #var int
*/
protected $minAge;
/**
* #ORM\Column(type="integer")
* #NotBlank()
* #var int
*/
protected $maxAge;
/**
* #ORM\OneToMany(targetEntity="RefAgeClassHighscoreList", mappedBy="ageClass", cascade={"persist"})
* #var PersistentCollection
*/
private $ageClassHighscoreLists;
/**
* AgeClass constructor.
*/
function __construct()
{
$this->setGuid(GuidHelper::generateGuid());
$this->setValidFrom(new \DateTime());
}
/**
* #return int
*/
public function getMinAge()
{
return $this->minAge;
}
/**
* #param int $minAge
* #return AgeClass
*/
public function setMinAge($minAge)
{
$this->minAge = $minAge;
return $this;
}
/**
* #return int
*/
public function getMaxAge()
{
return $this->maxAge;
}
/**
* #param int $maxAge
* #return AgeClass
*/
public function setMaxAge($maxAge)
{
$this->maxAge = $maxAge;
return $this;
}
/**
* #return array
*/
public function getAgeClassHighscoreLists()
{
if($this->ageClassHighscoreLists == null)
return array();
return $this->ageClassHighscoreLists->toArray();
}
/**
* #param PersistentCollection $valuationClasses
* #return AgeClass
*/
public function seAgeClassHighscoreLists($valuationClasses)
{
$this->ageClassHighscoreLists = $valuationClasses;
return $this;
}
/**
* #return HighscoreList[]
*/
public function getHighscoreLists()
{
return array_map(
function ($ageClassHighscoreList) {
/** #var RefAgeClassHighscoreList $ageClassHighscoreList */
return $ageClassHighscoreList->getHighscoreList();
},
$this->getAgeClassHighscoreLists()
);
}
/**
* #param RefAgeClassHighscoreList $ageClassHighscoreList
* #return $this
*/
public function addAgeClassHighscoreList($ageClassHighscoreList)
{
if (!$this->ageClassHighscoreLists->contains($ageClassHighscoreList)) {
$this->ageClassHighscoreLists->add($ageClassHighscoreList);
$ageClassHighscoreList->setAgeClass($this);
}
return $this;
}
}
HighscoreList
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\DSV\Core\BaseDSVCoreDataRepository")
* */
class HighscoreList extends BaseDSVCoreData
{
/**
* #ORM\OneToMany(targetEntity="RefAgeClassHighscoreList", mappedBy="highscoreList", cascade={"persist"})
* #var PersistentCollection
*/
private $ageClassHighscoreLists;
function __construct()
{
$this->setGuid(GuidHelper::generateGuid());
}
/**
* #return PersistentCollection
*/
public function getAgeClassReferences()
{
return $this->ageClassHighscoreLists;
}
/**
* #param PersistentCollection $valuationClasses
* #return AgeClass
*/
public function setAgeClassReferences($valuationClasses)
{
$this->ageClassReferences = $valuationClasses;
return $this;
}
/**
* #return AgeClass[]
*/
public function getAgeClasses()
{
return array_map(
function ($ageClassHighscoreList) {
/** #var RefAgeClassHighscoreList $ageClassHighscoreList */
return $ageClassHighscoreList->getAgeClass();
},
$this->ageClassHighscoreLists->toArray()
);
}
/**
* #param RefAgeClassHighscoreList $ageClassHighscoreList
* #return HighscoreList
*/
public function addAgeClassReference($ageClassHighscoreList)
{
if (!$this->ageClassHighscoreLists->contains($ageClassHighscoreList)) {
$this->ageClassHighscoreLists->add($ageClassHighscoreList);
$ageClassHighscoreList->setHighscoreList($this);
}
return $this;
}
}
}
RefAgeClassHighscoreList
/**
* #ORM\Entity()
* */
class RefAgeClassHighscoreList implements IVersionable
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(type="datetime")
*/
protected $validFrom;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $validTo;
/**
* #ORM\ManyToOne(targetEntity="AgeClass", inversedBy="highscoreListReferences")
* #ORM\JoinColumn(name="ageclass_id", referencedColumnName="id", nullable=FALSE)
*/
protected $ageClass;
/**
* #ORM\ManyToOne(targetEntity="highscoreList", inversedBy="ageClassReferences")
* #ORM\JoinColumn(name="highscorelist_id", referencedColumnName="id", nullable=FALSE)
*/
protected $highscoreList;
protected $hasChanges = false;
/**
* #see IVersionable
*/
public function getId()
{
return $this->id;
}
/**
* #see IVersionable
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #see IVersionable
*/
public function getGuid()
{
return null;
}
/**
* #see IVersionable
*/
public function setGuid($guid)
{
return $this;
}
/**
* #see IVersionable
*/
public function getValidFrom()
{
return $this->validFrom;
}
/**
* #see IVersionable
*/
public function setValidFrom($validFrom)
{
$this->validFrom = $validFrom;
return $this;
}
/**
* #see IVersionable
*/
public function getValidTo()
{
return $this->validTo;
}
/**
* #see IVersionable
*/
public function setValidTo($validTo)
{
$this->validTo = $validTo;
return $this;
}
/**
* #see IVersionable
*/
public function isValid()
{
return ($this->validTo == null);
}
/**
* #see IVersionable
*/
public function createNewVersion()
{
$newVersion = clone $this;
$newVersion->setValidFrom(new \DateTime());
return $newVersion;
}
/**
* #see IVersionable
*/
public function hasChanges()
{
return $this->hasChanges;
}
/**
* #return AgeClass
*/
public function getAgeClass()
{
return $this->ageClass;
}
/**
* #param AgeClass $ageClass
* #return RefAgeClassHighscoreList
*/
public function setAgeClass($ageClass)
{
$this->ageClass = $ageClass;
return $this;
}
/**
* #return HighscoreList
*/
public function getHighscoreList()
{
return $this->highscoreList;
}
/**
* #param HighscoreList $highscoreList
* #return RefAgeClassHighscoreList
*/
public function setHighscoreList($highscoreList)
{
$this->gighscoreList = $highscoreList;
return $this;
}
}
Well, you have a very recurrent and tedious problem. You can do an embed form with AgeClass and embedding a form for RefAgeClassHighscoreList type. In that embedded form you can have an attribute of type HighscoreList , the problem is that the default rendered component for what you need is a multi-select list of HighscoreList, you can see it putting the attribute multiple = true to the property of HighscoreList.
For transform that list to a check-box list you need to create a custom theme extending or adding new blocks to the default one provided by symfony. My advice is to create new widgets and rows for your specific form using the form name. You can find a lot of documentation about what I mention and need to get a small part of each one to do what you ask.
Hope all this clues help you.

how to connect to couchdb database using couchdb4j api with username and password?

I am using couchdb4j api to establish a connection through session object with couchdb(version 0.11.2).
Couchdb database is protected with username and password,
trying to establish connection with
Session(String host, int port, String user, String pass, boolean usesAuth, boolean secure) constructor by providing host,port,user,pass and usersAuth true, secure false,
but it is unable to establish a connection with username and password and giving a warning Authentication error: Unable to respond to any of these challenges: {}.
I used correct username and password.
Try a CouchDB lib that is actively maintained http://www.ektorp.org/ instead.
I solved the same issue by writing a simple Curl class that simplified the communication and return JSON in String form, since that is what is returned.
It should be self explanatory and you can read the main method for hints.
package path.to.the.class;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import Log;
/**
* This class takes on the simple task of doing http calls to any http web service like a web page or alike. Since the
* class is streamlined for JSON use this is the most easiest to set up.
*
* #author mikael.p.larsson#epsilon.nu
*
*/
public class Curl {
private Map<String, String> requestProperties = null;
private String charsetName = "UTF8";
public static final String GET = "GET";
public static final String PUT = "PUT";
public static final String POST = "POST";
public static final String HEAD = "HEAD";
public static final String DELETE = "DELETE";
/**
* This is the default constructor for Curl which takes it for granted that you want to communicate and read JSON.
* Most of the times this approach works even if plain html or text is requested.
*/
public Curl() {
requestProperties = new HashMap<String, String>();
requestProperties.put("Content-Type", "application/json");
}
/**
* With this alternate constructor a map containing header strings can be provided, useful if something apart from
* JSON is to be consumed.
*
* #param requestProperties
* a Map containing the header strings.
*/
public Curl(Map<String, String> requestProperties) {
this.requestProperties = requestProperties;
}
/**
* Public setter to enable setting charsetName.
*
* #param charsetName
* #return this instance to enable on liners.
*/
public Curl setCharsetName(String charsetName) {
this.charsetName = charsetName;
return this;
}
/**
* In the world of the web this is the command that a web browser does for you after you have entered an url into
* the address field. When using GET there should be no side effects on the site the data was requested from; the
* get method only consumes data and sends nothing.
*
* #param urlAsString
* the url to fetch from the internet.
* #return The response from the server
*/
public String get(String urlAsString) {
return doHttpCall(urlAsString, GET, null);
}
/**
* Put should be used when a resource should be sent to a server.
*
* #param urlAsString
* the url to the resource.
* #param doc
* the content to put
* #return The response from the server.
*/
public String put(String urlAsString, String doc) {
return doHttpCall(urlAsString, "PUT", doc);
}
/**
* Post should be used when a resource should be posted to a server.
*
* #param urlAsString
* the url to the resource.
* #param doc
* the content to put
* #return The response from the server.
*/
public String post(String urlAsString, String doc) {
return doHttpCall(urlAsString, "POST", doc);
}
/**
* Mostly to be considered as a get without the contents, Here implemented as an is the resource available function.
*
* #param urlAsString
* the url to the resource.
* #return The responseMessage from the server.
*/
public String head(String urlAsString) {
return doHttpCall(urlAsString, "HEAD", null);
}
/**
* Deletes a resource from an url. Be careful!
*
* #param urlAsString
* The url to the resource to delete.
* #return The response from the server.
*/
public String delete(String urlAsString) {
try {
return doHttpCall(urlAsString, "DELETE", null);
} catch (Exception e) {
Log.warn("No object to delete found at " + urlAsString + ".");
return "No object to delete found at " + urlAsString + ".";
}
}
/**
* This method does the actual HTTP communication to simplify the methods above.
*
* #param urlAsString
* The url to resource in question.
* #param method
* The method to be used.
* #param doc
* The resource to send or null if none.
* #return The response from the server.
*/
private String doHttpCall(String urlAsString, String method, String doc) {
StringBuffer result = new StringBuffer();
HttpURLConnection httpUrlConnection = null;
try {
URL url = new URL(urlAsString);
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setDoInput(true);
httpUrlConnection.setRequestMethod(method);
if (url.getUserInfo() != null) {
String basicAuth = "Basic " + new String(new Base64().encode(url.getUserInfo().getBytes()));
httpUrlConnection.setRequestProperty("Authorization", basicAuth);
}
httpUrlConnection.setRequestProperty("Content-Length", "0");
for (String key : requestProperties.keySet()) {
httpUrlConnection.setRequestProperty(key, requestProperties.get(key));
}
if (doc != null && !doc.isEmpty()) {
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setRequestProperty("Content-Length", "" + doc.getBytes(charsetName));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(httpUrlConnection.getOutputStream(),
charsetName);
outputStreamWriter.write(doc);
outputStreamWriter.close();
}
readInputStream(result, httpUrlConnection.getInputStream());
} catch (RuntimeException e) {
Log.info(e.getMessage());
} catch (MalformedURLException e) {
Log.warn("The url '" + urlAsString + "' is malformed.");
} catch (IOException e) {
try {
result.append(e.getMessage());
readInputStream(result, httpUrlConnection.getErrorStream());
if ("".equals(result.toString())) {
result.append("Error ");
result.append(httpUrlConnection.getResponseCode());
result.append(" : ");
result.append(httpUrlConnection.getResponseMessage());
result.append(". Exception message is: [");
result.append(e.getMessage());
result.append("]");
}
} catch (IOException e1) {
}
} finally {
if ("HEAD".equalsIgnoreCase(method)) {
try {
result.append(httpUrlConnection.getResponseMessage());
} catch (IOException e) {
Log.fatal("This is as low as we can get, nothing worked!");
e.printStackTrace();
}
}
if (httpUrlConnection != null)
httpUrlConnection.disconnect();
}
return result.toString();
}
/**
* Local helper method that reads data from an inputstream.
*
* #param result
* The read text.
* #param inputStream
* The stream to read.
* #throws UnsupportedEncodingException
* #throws IOException
*/
private void readInputStream(StringBuffer result, InputStream inputStream) throws UnsupportedEncodingException,
IOException {
if (inputStream == null)
throw new IOException("No working inputStream.");
InputStreamReader streamReader = new InputStreamReader(inputStream, charsetName);
BufferedReader bufferedReader = new BufferedReader(streamReader);
String row;
while ((row = bufferedReader.readLine()) != null) {
result.append(row);
result.append("\n");
}
bufferedReader.close();
streamReader.close();
}
/**
* A main method to provide the possibility to use this exact class from the command line.
* <p>
* usage:
* <code>java -cp target/classes/. path.to.the.class.Curl http://server.domain.nu:port/path/to/resource method [data]</code>
* </p>
*
* #param args
* in order: url method data
*/
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("usage: Curl path method [data]");
System.exit(0);
}
String url = args[0];
String method = args[1];
String data = args.length == 3 ? args[2] : null;
Curl curl = new Curl();
if (method.equals("head")) {
System.out.println(curl.head(url));
System.exit(0);
}
if (method.equals("put")) {
System.out.println(curl.put(url, data));
System.exit(0);
}
System.out.println(curl.doHttpCall(url, method, data));
}
}
Try change configuration parameter required_valid_user to true

JSF2.0 simple file input

I'm trying to add a very simple file input to my webapp which I'm doing using JSF2.0 and RichFaces 3.3.3, the thing is I really dislike the richfaces fileInput component and I'm looking for something simpler (in terms of use and looks), so far I've found:
tomahawk's fileInput - but tomahawk only supports JSF1.2
trinidad fileInput - but trinidad for JSF2.0 is in alpha stage
primefaces - but of course they won't work with RichFaces 3.3.3 (only 4.0 which are in beta)
Are there any other options? I need something really simple like a normal html file input component.
You basically need to do two things:
Create a Filter which puts the multipart/form-data items in a custom map and replace the original request parameter map with it so that the normal request.getParameter() process keeps working.
Create a JSF 2.0 custom component which renders a input type="file" and which is aware of this custom map and can obtain the uploaded files from it.
#taher has already given a link where you could find insights and code snippets. The JSF 2.0 snippets should be reuseable. You yet have to modify the MultipartMap to use the good 'ol Apache Commons FileUpload API instead of the Servlet 3.0 API.
If I have time, I will by end of day rewrite it and post it here.
Update: I almost forgot you, I did a quick update to replace Servlet 3.0 API by Commons FileUpload API, it should work:
package net.balusc.http.multipart;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
public class MultipartMap extends HashMap<String, Object> {
// Constants ----------------------------------------------------------------------------------
private static final String ATTRIBUTE_NAME = "parts";
private static final String DEFAULT_ENCODING = "UTF-8";
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
// Vars ---------------------------------------------------------------------------------------
private String encoding;
private String location;
// Constructors -------------------------------------------------------------------------------
/**
* Construct multipart map based on the given multipart request and file upload location. When
* the encoding is not specified in the given request, then it will default to <tt>UTF-8</tt>.
* #param multipartRequest The multipart request to construct the multipart map for.
* #param location The location to save uploaded files in.
* #throws ServletException If something fails at Servlet level.
* #throws IOException If something fails at I/O level.
*/
#SuppressWarnings("unchecked") // ServletFileUpload#parseRequest() isn't parameterized.
public MultipartMap(HttpServletRequest multipartRequest, String location)
throws ServletException, IOException
{
multipartRequest.setAttribute(ATTRIBUTE_NAME, this);
this.encoding = multipartRequest.getCharacterEncoding();
if (this.encoding == null) {
multipartRequest.setCharacterEncoding(this.encoding = DEFAULT_ENCODING);
}
this.location = location;
try {
List<FileItem> parts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(multipartRequest);
for (FileItem part : parts) {
if (part.isFormField()) {
processFormField(part);
} else if (!part.getName().isEmpty()) {
processFileField(part);
}
}
} catch (FileUploadException e) {
throw new ServletException("Parsing multipart/form-data request failed.", e);
}
}
// Actions ------------------------------------------------------------------------------------
#Override
public Object get(Object key) {
Object value = super.get(key);
if (value instanceof String[]) {
String[] values = (String[]) value;
return values.length == 1 ? values[0] : Arrays.asList(values);
} else {
return value; // Can be File or null.
}
}
/**
* #see ServletRequest#getParameter(String)
* #throws IllegalArgumentException If this field is actually a File field.
*/
public String getParameter(String name) {
Object value = super.get(name);
if (value instanceof File) {
throw new IllegalArgumentException("This is a File field. Use #getFile() instead.");
}
String[] values = (String[]) value;
return values != null ? values[0] : null;
}
/**
* #see ServletRequest#getParameterValues(String)
* #throws IllegalArgumentException If this field is actually a File field.
*/
public String[] getParameterValues(String name) {
Object value = super.get(name);
if (value instanceof File) {
throw new IllegalArgumentException("This is a File field. Use #getFile() instead.");
}
return (String[]) value;
}
/**
* #see ServletRequest#getParameterNames()
*/
public Enumeration<String> getParameterNames() {
return Collections.enumeration(keySet());
}
/**
* #see ServletRequest#getParameterMap()
*/
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = new HashMap<String, String[]>();
for (Entry<String, Object> entry : entrySet()) {
Object value = entry.getValue();
if (value instanceof String[]) {
map.put(entry.getKey(), (String[]) value);
} else {
map.put(entry.getKey(), new String[] { ((File) value).getName() });
}
}
return map;
}
/**
* Returns uploaded file associated with given request parameter name.
* #param name Request parameter name to return the associated uploaded file for.
* #return Uploaded file associated with given request parameter name.
* #throws IllegalArgumentException If this field is actually a Text field.
*/
public File getFile(String name) {
Object value = super.get(name);
if (value instanceof String[]) {
throw new IllegalArgumentException("This is a Text field. Use #getParameter() instead.");
}
return (File) value;
}
// Helpers ------------------------------------------------------------------------------------
/**
* Process given part as Text part.
*/
private void processFormField(FileItem part) {
String name = part.getFieldName();
String[] values = (String[]) super.get(name);
if (values == null) {
// Not in parameter map yet, so add as new value.
put(name, new String[] { part.getString() });
} else {
// Multiple field values, so add new value to existing array.
int length = values.length;
String[] newValues = new String[length + 1];
System.arraycopy(values, 0, newValues, 0, length);
newValues[length] = part.getString();
put(name, newValues);
}
}
/**
* Process given part as File part which is to be saved in temp dir with the given filename.
*/
private void processFileField(FileItem part) throws IOException {
// Get filename prefix (actual name) and suffix (extension).
String filename = FilenameUtils.getName(part.getName());
String prefix = filename;
String suffix = "";
if (filename.contains(".")) {
prefix = filename.substring(0, filename.lastIndexOf('.'));
suffix = filename.substring(filename.lastIndexOf('.'));
}
// Write uploaded file.
File file = File.createTempFile(prefix + "_", suffix, new File(location));
InputStream input = null;
OutputStream output = null;
try {
input = new BufferedInputStream(part.getInputStream(), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(new FileOutputStream(file), DEFAULT_BUFFER_SIZE);
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}
put(part.getFieldName(), file);
part.delete(); // Cleanup temporary storage.
}
}
You still need both the MultipartFilter and MultipartRequest classes as described in this article. You only need to remove the #WebFilter annotation and map the filter on an url-pattern of /* along with an <init-param> of location wherein you specify the absolute path where the uploaded files are to be stored. You can use the JSF 2.0 custom file upload component as described in this article unchanged.
Dear either you have to use rich:uploadFile or make custom component in JSF by following http://balusc.blogspot.com/2009/12/uploading-files-with-jsf-20-and-servlet.html
After I also tried tomahawk, I mentioned that it does not work with AJAX. So I decided to hack rich:fileUpload and perform the click on add button over a a4j:commandButton. Here's the code:
<a4j:form id="myForm">
<a4j:commandButton id="myButton" value="Upload" title="Upload" styleClass="myButtonClass"
onclick="document.getElementById('myForm:myFileUpload:file').click()/>
<rich:fileUpload id="myFileUpload" maxFilesQuantity="1" autoclear="true"
immediateUpload="true" styleClass="invisibleClass"
fileUploadListener="#{uploadBean.uploadListener}"/>
</a4j:form>
myForm:myFileUpload:file is the input-Element (type="file") for the Add-Button. invisibleClass should only contain display:none;. With style="display:none;" it won't work.
You can used rich faces 3.3.3 file upload.
Step 1 : fileUpload.xhtml
<rich:fileUpload id="fileupload" addControlLabel="Browse"
required="true"
fileUploadListener="#{testForm.listener}"
acceptedTypes="xml"
ontyperejected="alert('Only xml files are accepted');"
maxFilesQuantity="1" listHeight="57px" listWidth="100%"
disabled="#{testForm..disabled}" >
<a4j:support event="onclear"
action="#{testForm..clearUploadData}"
reRender="fileupload" />
</rich:fileUpload>
Step 2: FileUpload.java
public class FileUpload implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String Name;
private String mime;
private long length;
private byte [] file;
private String absolutePath;
public String getName() {
return Name;
}
/**
* #return the file
*/
public byte[] getFile() {
return file;
}
/**
* #param file the file to set
*/
public void setFile(byte[] file) {
this.file = file;
}
/**
* #param mime the mime to set
*/
public void setMime(String mime) {
this.mime = mime;
}
public void setName(String name) {
Name = name;
int extDot = name.lastIndexOf('.');
if(extDot > 0){
String extension = name.substring(extDot +1);
if("txt".equals(extension)){
mime="txt";
} else if("xml".equals(extension)){
mime="xml";
} else {
mime = "unknown file";
}
}
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
public String getMime(){
return mime;
}
/**
* #return the absolutePath
*/
public String getAbsolutePath() {
return absolutePath;
}
/**
* #param absolutePath the absolutePath to set
*/
public void setAbsolutePath(String absolutePath) {
this.absolutePath = absolutePath;
}
}
Step 3 :TestForm // calling listner
/**
*
* #param event
* #throws Exception
*/
public void listener(UploadEvent event) throws Exception{
UploadItem item = event.getUploadItem();
FileUpload file = new FileUpload();
file.setLength(item.getData().length);
file.setFile(item.getData());
file.setName(item.getFileName());
files.add(file);
}

Resources