volitelné zamykání souborů (POSIX) a zaslání notifikace ostatním aplikacím (inotify/CLOSE_WRITE)
1.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Atribut.java Mon Dec 11 00:49:59 2023 +0100
1.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Atribut.java Tue Dec 12 21:19:11 2023 +0100
1.3 @@ -19,6 +19,9 @@
1.4 import java.nio.ByteBuffer;
1.5 import java.nio.charset.Charset;
1.6
1.7 +/**
1.8 + * @author Ing. František Kučera (frantovo.cz)
1.9 + */
1.10 public class Atribut {
1.11
1.12 private String klíč;
2.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Překlady_cs.properties Mon Dec 11 00:49:59 2023 +0100
2.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Překlady_cs.properties Tue Dec 12 21:19:11 2023 +0100
2.3 @@ -5,6 +5,8 @@
2.4 chyba.chyb\u00edParametr=O\u010dek\u00e1v\u00e1m pr\u00e1v\u011b jeden parametr \u2013 n\u00e1zev souboru.
2.5 chyba.nepoda\u0159iloSeSmazat=Nepoda\u0159ilo se smazat atribut.
2.6 chyba.nepoda\u0159iloSeNa\u010d\u00edst=Nepoda\u0159ilo se na\u010d\u00edst atributy.
2.7 +chyba.nepoda\u0159iloSeNastavitZ\u00e1mek=Nepoda\u0159ilo se nastavit z\u00e1mek.
2.8 +chyba.lzeZamknoutJenSoubor=Je podporov\u00e1no zamyk\u00e1n\u00ed pouze norm\u00e1ln\u00edch sobour\u016f ne adres\u00e1\u0159\u016f atd.
2.9
2.10 tabulka.n\u00e1zev=N\u00e1zev
2.11 tabulka.hodnota=Hodnota
2.12 @@ -12,3 +14,5 @@
2.13 p\u0159idatAtribut=P\u0159idat atribut
2.14 smazatAtribut=Smazat atribut
2.15 znovuNa\u010d\u00edst=Znovu na\u010d\u00edst
2.16 +zamknout=Zamknout
2.17 +zamknout.popis=Otev\u0159e soubor pro z\u00e1pis a vytvo\u0159\u00ed na n\u011bm z\u00e1mek. P\u0159i odemknut\u00ed uvoln\u00ed z\u00e1mek a zav\u0159e soubor.
3.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Překlady_en.properties Mon Dec 11 00:49:59 2023 +0100
3.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Překlady_en.properties Tue Dec 12 21:19:11 2023 +0100
3.3 @@ -5,6 +5,8 @@
3.4 chyba.chyb\u00edParametr=Expecting one parameter \u2013 file name.
3.5 chyba.nepoda\u0159iloSeSmazat=Failed to delete the attribute.
3.6 chyba.nepoda\u0159iloSeNa\u010d\u00edst=Failed to load attributes.
3.7 +chyba.nepoda\u0159iloSeNastavitZ\u00e1mek=Unable to lock the file.
3.8 +chyba.lzeZamknoutJenSoubor=File locking is supported only for regular files, not for directories or specials.
3.9
3.10 tabulka.n\u00e1zev=Name
3.11 tabulka.hodnota=Value
3.12 @@ -12,3 +14,5 @@
3.13 p\u0159idatAtribut=Add attribute
3.14 smazatAtribut=Delete attribute
3.15 znovuNa\u010d\u00edst=Reload all
3.16 +zamknout=Lock
3.17 +zamknout.popis=Open the file for write and lock it. On unlocking, release the lock and close the file.
4.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Startér.java Mon Dec 11 00:49:59 2023 +0100
4.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/Startér.java Tue Dec 12 21:19:11 2023 +0100
4.3 @@ -41,10 +41,10 @@
4.4 * http://today.java.net/pub/a/today/2008/07/03/jsr-203-new-file-apis.html
4.5 * #so-what-is-a-path-really
4.6 *
4.7 - * $ setfattr -n "user.fiki.pozdrav" -v 'Dobrý den!' pokus.txt
4.8 + * $ setfattr -n "user.franta.pozdrav" -v 'Dobrý den!' pokus.txt
4.9 * (v javě pak pracujeme s klíči bez předpony „user.“)
4.10 - *
4.11 - * @author fiki
4.12 + *
4.13 + * @author Ing. František Kučera (frantovo.cz)
4.14 */
4.15 public class Startér {
4.16
5.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/gui/Model.java Mon Dec 11 00:49:59 2023 +0100
5.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/gui/Model.java Tue Dec 12 21:19:11 2023 +0100
5.3 @@ -19,7 +19,10 @@
5.4 import cz.frantovo.rozsireneatributy.Atribut;
5.5 import java.io.File;
5.6 import java.io.IOException;
5.7 +import java.io.RandomAccessFile;
5.8 import java.nio.ByteBuffer;
5.9 +import java.nio.channels.FileChannel;
5.10 +import java.nio.channels.FileLock;
5.11 import java.nio.file.Path;
5.12 import java.nio.file.attribute.UserDefinedFileAttributeView;
5.13 import java.nio.file.spi.FileSystemProvider;
5.14 @@ -35,8 +38,7 @@
5.15 import javax.swing.table.TableModel;
5.16
5.17 /**
5.18 - *
5.19 - * @author fiki
5.20 + * @author Ing. František Kučera (frantovo.cz)
5.21 */
5.22 public class Model implements TableModel {
5.23
5.24 @@ -49,10 +51,16 @@
5.25 překlady.getString("tabulka.hodnota")
5.26 };
5.27 private Set<TableModelListener> posluchače = new HashSet<>();
5.28 + private File soubor;
5.29 private UserDefinedFileAttributeView souborovýSystém;
5.30 private List<Atribut> atributy = new ArrayList<>();
5.31
5.32 + private RandomAccessFile zámekSoubor;
5.33 + private FileChannel zámekKanál;
5.34 + private FileLock zámek;
5.35 +
5.36 public Model(File soubor) throws IOException {
5.37 + this.soubor = soubor;
5.38 Path cesta = soubor.toPath();
5.39 FileSystemProvider posyktovatelFS = cesta.getFileSystem().provider();
5.40 souborovýSystém = posyktovatelFS
5.41 @@ -172,4 +180,29 @@
5.42 p.tableChanged(new TableModelEvent(this));
5.43 }
5.44 }
5.45 +
5.46 + public boolean isZámekPodporovaný() {
5.47 + return soubor.isFile();
5.48 + }
5.49 +
5.50 + public void nastavZámek(boolean zamknout) throws IOException {
5.51 + if (!isZámekPodporovaný()) {
5.52 + throw new IOException(překlady
5.53 + .getString("chyba.lzeZamknoutJenSoubor"));
5.54 + }
5.55 +
5.56 + if (zamknout && zámekSoubor == null) {
5.57 + zámekSoubor = new RandomAccessFile(soubor, "rw");
5.58 + zámekKanál = zámekSoubor.getChannel();
5.59 + zámek = zámekKanál.lock();
5.60 + } else if (!zamknout && zámekSoubor != null) {
5.61 + zámek.release();
5.62 + zámekKanál.close();
5.63 + zámekSoubor.close();
5.64 + zámek = null;
5.65 + zámekKanál = null;
5.66 + zámekSoubor = null;
5.67 + }
5.68 +
5.69 + }
5.70 }
6.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/gui/Panel.form Mon Dec 11 00:49:59 2023 +0100
6.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/gui/Panel.form Tue Dec 12 21:19:11 2023 +0100
6.3 @@ -23,7 +23,9 @@
6.4 <Component id="tlačítkoSmazat" min="-2" max="-2" attributes="0"/>
6.5 <EmptySpace max="-2" attributes="0"/>
6.6 <Component id="tlačítkoZnovuNačíst" min="-2" max="-2" attributes="0"/>
6.7 - <EmptySpace pref="222" max="32767" attributes="0"/>
6.8 + <EmptySpace max="-2" attributes="0"/>
6.9 + <Component id="tlačítkoZamknout" min="-2" max="-2" attributes="0"/>
6.10 + <EmptySpace pref="122" max="32767" attributes="0"/>
6.11 </Group>
6.12 <Component id="posuvnýPanel" alignment="0" pref="543" max="32767" attributes="0"/>
6.13 </Group>
6.14 @@ -37,6 +39,7 @@
6.15 <Component id="tlačítkoPřidat" alignment="3" min="-2" max="-2" attributes="0"/>
6.16 <Component id="tlačítkoSmazat" alignment="3" min="-2" max="-2" attributes="0"/>
6.17 <Component id="tlačítkoZnovuNačíst" alignment="3" min="-2" max="-2" attributes="0"/>
6.18 + <Component id="tlačítkoZamknout" alignment="3" min="-2" max="-2" attributes="0"/>
6.19 </Group>
6.20 <EmptySpace max="-2" attributes="0"/>
6.21 </Group>
6.22 @@ -82,5 +85,15 @@
6.23 <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tlačítkoZnovuNačístActionPerformed"/>
6.24 </Events>
6.25 </Component>
6.26 + <Component class="javax.swing.JToggleButton" name="tlačítkoZamknout">
6.27 + <Properties>
6.28 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
6.29 + <ResourceString bundle="cz/frantovo/rozsireneatributy/Překlady.properties" key="zamknout" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
6.30 + </Property>
6.31 + </Properties>
6.32 + <Events>
6.33 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tlačítkoZamknoutActionPerformed"/>
6.34 + </Events>
6.35 + </Component>
6.36 </SubComponents>
6.37 </Form>
7.1 --- a/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/gui/Panel.java Mon Dec 11 00:49:59 2023 +0100
7.2 +++ b/java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/gui/Panel.java Tue Dec 12 21:19:11 2023 +0100
7.3 @@ -28,8 +28,7 @@
7.4 import javax.swing.event.ListSelectionListener;
7.5
7.6 /**
7.7 - *
7.8 - * @author fiki
7.9 + * @author Ing. František Kučera (frantovo.cz)
7.10 */
7.11 public class Panel extends javax.swing.JPanel {
7.12
7.13 @@ -46,6 +45,11 @@
7.14 this.model = model;
7.15 initComponents();
7.16
7.17 + tlačítkoZamknout.setEnabled(model.isZámekPodporovaný());
7.18 + tlačítkoZamknout.setToolTipText(model.isZámekPodporovaný()
7.19 + ? překlady.getString("zamknout.popis")
7.20 + : překlady.getString("chyba.lzeZamknoutJenSoubor"));
7.21 +
7.22 tabulka = new JTable(model);
7.23 nastavEditor();
7.24 tabulka.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
7.25 @@ -85,8 +89,9 @@
7.26 }
7.27
7.28 private void zobrazChybovouHlášku(String hláška, Throwable chyba) {
7.29 - JOptionPane.showMessageDialog(this, hláška,
7.30 - překlady.getString("chyba"), JOptionPane.ERROR_MESSAGE);
7.31 + JOptionPane.showMessageDialog(this, hláška + "\n"
7.32 + + chyba.getLocalizedMessage(),
7.33 + překlady.getString("chyba.titulek"), JOptionPane.ERROR_MESSAGE);
7.34 log.log(Level.WARNING, hláška, chyba);
7.35 }
7.36
7.37 @@ -98,6 +103,7 @@
7.38 tlačítkoPřidat = new javax.swing.JButton();
7.39 tlačítkoSmazat = new javax.swing.JButton();
7.40 tlačítkoZnovuNačíst = new javax.swing.JButton();
7.41 + tlačítkoZamknout = new javax.swing.JToggleButton();
7.42
7.43 tlačítkoPřidat.setMnemonic('p');
7.44 java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("cz/frantovo/rozsireneatributy/Překlady"); // NOI18N
7.45 @@ -125,6 +131,13 @@
7.46 }
7.47 });
7.48
7.49 + tlačítkoZamknout.setText(bundle.getString("zamknout")); // NOI18N
7.50 + tlačítkoZamknout.addActionListener(new java.awt.event.ActionListener() {
7.51 + public void actionPerformed(java.awt.event.ActionEvent evt) {
7.52 + tlačítkoZamknoutActionPerformed(evt);
7.53 + }
7.54 + });
7.55 +
7.56 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
7.57 this.setLayout(layout);
7.58 layout.setHorizontalGroup(
7.59 @@ -136,7 +149,9 @@
7.60 .addComponent(tlačítkoSmazat)
7.61 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
7.62 .addComponent(tlačítkoZnovuNačíst)
7.63 - .addContainerGap(222, Short.MAX_VALUE))
7.64 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
7.65 + .addComponent(tlačítkoZamknout)
7.66 + .addContainerGap(122, Short.MAX_VALUE))
7.67 .addComponent(posuvnýPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 543, Short.MAX_VALUE)
7.68 );
7.69 layout.setVerticalGroup(
7.70 @@ -147,7 +162,8 @@
7.71 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
7.72 .addComponent(tlačítkoPřidat)
7.73 .addComponent(tlačítkoSmazat)
7.74 - .addComponent(tlačítkoZnovuNačíst))
7.75 + .addComponent(tlačítkoZnovuNačíst)
7.76 + .addComponent(tlačítkoZamknout))
7.77 .addContainerGap())
7.78 );
7.79 }// </editor-fold>//GEN-END:initComponents
7.80 @@ -173,10 +189,21 @@
7.81 .getString("chyba.nepodařiloSeNačíst"), e);
7.82 }
7.83 }//GEN-LAST:event_tlačítkoZnovuNačístActionPerformed
7.84 +
7.85 + private void tlačítkoZamknoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tlačítkoZamknoutActionPerformed
7.86 + try {
7.87 + model.nastavZámek(tlačítkoZamknout.isSelected());
7.88 + } catch (Exception e) {
7.89 + zobrazChybovouHlášku(překlady
7.90 + .getString("chyba.nepodařiloSeNastavitZámek"), e);
7.91 + }
7.92 + }//GEN-LAST:event_tlačítkoZamknoutActionPerformed
7.93 +
7.94 // Variables declaration - do not modify//GEN-BEGIN:variables
7.95 private javax.swing.JScrollPane posuvnýPanel;
7.96 private javax.swing.JButton tlačítkoPřidat;
7.97 private javax.swing.JButton tlačítkoSmazat;
7.98 + private javax.swing.JToggleButton tlačítkoZamknout;
7.99 private javax.swing.JButton tlačítkoZnovuNačíst;
7.100 // End of variables declaration//GEN-END:variables
7.101 }