View Javadoc

1   /**
2    * Copyright 2008 WebPhotos
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.webphotos.action;
17  
18  import com.google.common.collect.Collections2;
19  import com.google.common.collect.Sets;
20  import java.awt.event.ActionEvent;
21  import java.io.*;
22  import java.nio.channels.FileChannel;
23  import java.text.ParseException;
24  import java.text.SimpleDateFormat;
25  import java.util.Collection;
26  import java.util.Date;
27  import java.util.HashSet;
28  import java.util.Iterator;
29  import java.util.Set;
30  import java.util.logging.Level;
31  import java.util.logging.Logger;
32  import javax.sql.RowSet;
33  import javax.swing.AbstractAction;
34  import javax.swing.JButton;
35  import javax.swing.JOptionPane;
36  import javax.swing.JTable;
37  import net.sf.webphotos.Album;
38  import net.sf.webphotos.BancoImagem;
39  import net.sf.webphotos.PhotoDTO;
40  import net.sf.webphotos.dao.jpa.AlbumDAO;
41  import net.sf.webphotos.gui.PainelWebFotos;
42  import net.sf.webphotos.gui.util.TableModelAlbum;
43  import net.sf.webphotos.gui.util.TableModelFoto;
44  import net.sf.webphotos.model.AlbumVO;
45  import net.sf.webphotos.model.CategoryVO;
46  import net.sf.webphotos.model.PhotoVO;
47  import net.sf.webphotos.tools.Thumbnail;
48  import net.sf.webphotos.util.ApplicationContextResource;
49  import net.sf.webphotos.util.Util;
50  import net.sf.webphotos.util.legacy.CacheFTP;
51  
52  /**
53   * Altera ou cria albúns. Possui um construtor que recebe botões e tabelas de
54   * albúns e fotos, um método que idenfica a ação obtida pelo evento e outro
55   * método que executa uma série de passos para implementar as alterações.
56   */
57  public class AcaoAlterarAlbum extends AbstractAction {
58  
59      /**
60       *
61       */
62      private static final long serialVersionUID = 7297664420604720262L;
63      JButton btAlterar, btNovo;
64      JTable tbAlbuns, tbFotos;
65      private RowSet rowSet = BancoImagem.getRSet();
66      private AlbumDAO albumDAO = (AlbumDAO) ApplicationContextResource.getBean("albunsDAO");
67      private boolean sucesso;
68  
69      /**
70       * Contrutor da classe. Recebe como parâmetro dois botões, um para alteração
71       * e o outro para implementação nova. Seta os valores dos botões da classe a
72       * partir dos recebidos e seta as tabelas de albúns e fotos a partir de
73       * métodos get da classe
74       * {@link net.sf.webphotos.gui.PainelWebFotos PainelWebFotos}.
75       *
76       * @param botaoNovo Botão para identificar a ação de implementação novo.
77       * @param botaoAlterar Botão para identificar a ação de alteração.
78       */
79      public AcaoAlterarAlbum(JButton botaoNovo, JButton botaoAlterar) {
80          btAlterar = botaoAlterar;
81          btNovo = botaoNovo;
82          tbAlbuns = PainelWebFotos.getTbAlbuns();
83          tbFotos = PainelWebFotos.getTbFotos();
84      }
85  
86      /**
87       * Identica qual a ação que ocorreu. Recebe como parâmetro um evento e
88       * verifica qual tipo de ação ocorreu por
89       * {@link java.util.EventObject#getSource() getSource} e pelo
90       * {@link javax.swing.AbstractButton#getActionCommand() getActionCommand}.
91       * Se o usuário clicou em <I>novo</I> cria um novo álbum, caso o texto do
92       * botão seja <I>cancelar</I>, então o usuário estará cancelando a criação
93       * de um novo albúm e por último, caso seja <I>alterar</I>, efetuará a
94       * atualização do álbum, coletando os valores dos controles GUI, validando
95       * os dados e atualizando o objeto.
96       *
97       * @param ev Evento de ação.
98       */
99      @Override
100     public void actionPerformed(ActionEvent ev) {
101         // usuario clicou em novo - criar novo álbum
102         if (ev.getSource() == btNovo && btNovo.getActionCommand().equals(PainelWebFotos.ACAO_NOVO)) {
103             PainelWebFotos.botaoNovo();
104         } // caso o texto do botão seja "cancelar", então o usuário está
105         // cancelando
106         // a criação de um novo álbum...
107         else if (btAlterar.getActionCommand().equals(PainelWebFotos.ACAO_CANCELAR) && ev.getSource() == btAlterar) {
108             PainelWebFotos.botaoCancelar();
109         } // atualiza o álbum, coletando os valores dos controles GUI, validando
110         // dados e atualizando o objeto Album
111         else if ((btAlterar.getActionCommand().equals(PainelWebFotos.ACAO_ALTERAR) && ev.getSource() == btAlterar) || (btNovo.getActionCommand().equals(PainelWebFotos.ACAO_FINALIZAR) && ev.getSource() == btNovo)) {
112             if (!PainelWebFotos.atualizaAlbum()) {
113                 return;
114             }
115             executaAlteracoes();
116             if (ev.getSource() == btNovo) {
117                 PainelWebFotos.botaoFinalizar();
118             }
119         }
120     }
121 
122     // executa alteracoes - alteracao ou criacao de novo album
123     /**
124      * Método responsável pelas alterações ou criação de um novo albúm. Primeiro
125      * faz o registro do albúm no banco de dados, checa se é necessário a
126      * criação de um novo albúm, criando um ID e atualizando o banco. Logo após
127      * registra as fotos no banco, todas as fotos são registradas novamente.
128      * Fotos novas recebem um ID. Faz um INSERT no banco e atualiza novamente.
129      * Move e renomeia os arquivos para o diretório do albúm. Faz os Thumbs para
130      * ajustar a dimensão das fotos e adciona no FTP. Limpa a flag
131      * CaminhoArquivo e apresenta as alterações. E por último, executar o
132      * sistema de envio por FTP.
133      */
134     public void executaAlteracoes() {
135 
136         Album album = Album.getAlbum();
137         PhotoDTO[] fotos = album.getFotos();
138         PhotoDTO f;
139         int albumID = album.getAlbumID();
140         sucesso = true;
141 
142         PainelWebFotos.setCursorWait(true);
143         
144         AlbumVO albumVO = null;
145 
146         // PASSO 1 - Carregar dados no BD
147         // //////////////////////////////////////////////////////////////////////
148         try {
149             final HashSet<PhotoDTO> newHashSet = Sets.newHashSet(fotos);
150             final Collection<PhotoVO> transformedCollection = Collections2.transform(newHashSet, PhotoDTO.FROM_PHOTODTO_PHOTOVO);
151             final HashSet<PhotoVO> photosVO = new HashSet<PhotoVO>(transformedCollection);
152             albumVO = AlbumVO.builder(albumID)
153                     .withAlbumName(album.getNmAlbum())
154                     .withDescription(album.getDescricao())
155                     .withCreationDate(parseDate(album.getDtInsercao()))
156                     .withCategory(new CategoryVO(album.getCategoriaID(), album.getCategoria(album.getCategoriaID())))
157                     .withPhotos(photosVO)
158                     .build();
159             albumDAO.save(albumVO);
160             
161             albumID = albumVO.getAlbumid();
162             album.setAlbumID(albumID);
163             
164             sucesso = true;
165         } catch (Exception ex) {
166             Logger.getLogger(AcaoAlterarAlbum.class.getName()).log(Level.SEVERE, null, ex);
167             sucesso = false;
168         }
169 
170         // PASSO 2 - Mover e renomear aquivos
171         // //////////////////////////////////////////////////////////////////////
172         String caminhoAlbum = Util.getFolder("albunsRoot").getPath() + File.separator + albumID;
173 
174         // checa a existencia do diretorio
175         File diretorioAlbum = new File(caminhoAlbum);
176         if (!diretorioAlbum.isDirectory()) {
177             // diretorio não existe... criamos
178             if (!diretorioAlbum.mkdir()) {
179                 Util.log("[AcaoAlterarAlbum.executaAlteracoes.7]/ERRO: diretorio " + caminhoAlbum + " não pode ser criado. abortando");
180                 return;
181             }
182         }
183 
184         // copia os arquivos
185         for (Iterator<PhotoVO> it = albumVO.getPhotos().iterator(); it.hasNext();) {
186             PhotoVO photoVO = it.next();
187             // copia somente arquivos ainda não cadastrados
188             if (photoVO.getCaminhoArquivo().length() > 0) {
189                 try {
190                     FileChannel canalOrigem = new FileInputStream(photoVO.getCaminhoArquivo()).getChannel();
191                     FileChannel canalDestino = new FileOutputStream(
192                             caminhoAlbum + File.separator + photoVO.getId() + ".jpg").getChannel();
193                     canalDestino.transferFrom(canalOrigem, 0, canalOrigem.size());
194                 } catch (Exception e) {
195                     Util.log("[AcaoAlterarAlbum.executaAlteracoes.8]/ERRO: " + e);
196                     sucesso = false;
197                 }
198             }
199         }// fim for
200 
201         prepareThumbsAndFTP(albumVO, caminhoAlbum);
202 
203         prepareExtraFiles(album, caminhoAlbum);
204 
205         fireChangesToGUI(fotos);
206 
207         dispatchAlbum();
208 
209         PainelWebFotos.setCursorWait(false);
210     }
211 
212     /**
213      * PASSO 3 - Fazer Thumbs e Adicionar em FTP
214      *
215      * @param fotos
216      * @param albumID
217      * @param caminhoAlbum
218      */
219     private void prepareThumbsAndFTP(AlbumVO albumVO, String caminhoAlbum) {
220         Set<PhotoVO> photoVOs = albumVO.getPhotos();
221         
222         for (Iterator<PhotoVO> it = photoVOs.iterator(); it.hasNext();) {
223             PhotoVO photoVO = it.next();
224 
225             String caminhoArquivo;
226 
227             // thumbs somente arquivos ainda não cadastrados
228             if (photoVO.getCaminhoArquivo().length() > 0) {
229                 caminhoArquivo = caminhoAlbum + File.separator + photoVO.getId() + ".jpg";
230                 Thumbnail.makeThumbs(caminhoArquivo);
231 
232                 // adicionar em CacheFTP
233                 CacheFTP.getCache().addCommand(CacheFTP.UPLOAD, albumVO.getAlbumid(),
234                         photoVO.getId());
235             }
236         }
237     }
238 
239     /**
240      * PASSO 4 - Preparar os arquivos adicionais
241      *
242      * @param album
243      * @param caminhoAlbum
244      */
245     private void prepareExtraFiles(Album album, String caminhoAlbum) {
246         // escreve o arquivo javaScript e o XML
247         try {
248             FileWriter out = new FileWriter(caminhoAlbum + File.separator + album.getAlbumID() + ".js");
249             out.write(album.toJavaScript());
250             out.flush();
251             out.close();
252 
253             out = new FileWriter(caminhoAlbum + File.separator + album.getAlbumID() + ".xml");
254             out.write(album.toXML());
255             out.flush();
256             out.close();
257 
258         } catch (IOException ex) {
259             ex.printStackTrace(Util.err);
260         }
261     }
262 
263     /**
264      * PASSO 5 - Limpar a flag CaminhoArquivo e apresentar as alterações
265      *
266      * @param fotos
267      */
268     private void fireChangesToGUI(PhotoDTO[] fotos) {
269         PhotoDTO f;
270 
271         for (int i = 0; i < fotos.length; i++) {
272             f = fotos[i];
273             f.resetCaminhoArquivo();
274         }
275 
276         try {
277             // Refresh of tables
278             TableModelFoto.getModel().update();
279             TableModelFoto.getModel().fireTableDataChanged();
280             TableModelAlbum.getModel().update();
281         } catch (Exception ex) {
282             ex.printStackTrace(Util.err);
283         }
284         TableModelAlbum.getModel().fireTableDataChanged();
285         ((javax.swing.table.AbstractTableModel) tbAlbuns.getModel()).fireTableDataChanged();
286         ((javax.swing.table.AbstractTableModel) tbFotos.getModel()).fireTableDataChanged();
287 
288         PainelWebFotos.alteracaoFinalizada();
289         if (sucesso) {
290             Util.log("Operação finalizada com sucesso.");
291         } else {
292             Util.log("Operação finalizada com erros.");
293         }
294     }
295 
296     /**
297      * PASSO 6 - Executar o sistema de envio por FTP
298      */
299     private void dispatchAlbum() {
300 
301         // TODO: Acertar uma rotina que peça confirmação em alguns casos
302         // //////////////////////////////////////////////////////////////////////
303         boolean autoTransferir = Util.getConfig().getBoolean("autoTransferir");
304         int retorno = 1;
305         if (!autoTransferir) {
306             retorno = JOptionPane.showConfirmDialog(
307                     PainelWebFotos.getInstance(),
308                     "Deseja publicar agora as fotos na internet?\n\nSE CLICAR EM \"NÃO\" SERÁ NECESSÁRIO ATIVAR A PUBLICAÇÃO MANUALMENTE!",
309                     "Publicar fotos?",
310                     JOptionPane.YES_NO_OPTION,
311                     JOptionPane.WARNING_MESSAGE);
312         }
313 
314         if (retorno == 0 || autoTransferir) {
315             Thread t = new Thread(new net.sf.webphotos.gui.util.FtpClient());
316             t.start();
317         }
318 
319     }
320 
321     private Date parseDate(final String dtInsercao) throws ParseException {
322         SimpleDateFormat dataBR = new SimpleDateFormat("dd/MM/yy");
323         Date dateParsed = dataBR.parse(dtInsercao);
324         return dateParsed;
325     }
326 }