4444import com .nextcloud .model .OCFileFilterType ;
4545import com .nextcloud .model .OfflineOperationRawType ;
4646import com .nextcloud .model .OfflineOperationType ;
47+ import com .nextcloud .model .ShareeEntry ;
4748import com .nextcloud .utils .date .DateFormatPattern ;
4849import com .nextcloud .utils .extensions .DateExtensionsKt ;
4950import com .owncloud .android .MainApp ;
@@ -111,6 +112,7 @@ public class FileDataStorageManager {
111112 public final FileDao fileDao = NextcloudDatabase .getInstance (MainApp .getAppContext ()).fileDao ();
112113 private final Gson gson = new Gson ();
113114 public final OfflineOperationsRepositoryType offlineOperationsRepository ;
115+ private final static int DEFAULT_CURSOR_INT_VALUE = -1 ;
114116
115117 public FileDataStorageManager (User user , ContentResolver contentResolver ) {
116118 this .contentProviderClient = null ;
@@ -1563,13 +1565,7 @@ private ContentValues createContentValueForShare(OCShare share) {
15631565 contentValues .put (ProviderTableMeta .OCSHARES_SHARE_LABEL , share .getLabel ());
15641566
15651567 FileDownloadLimit downloadLimit = share .getFileDownloadLimit ();
1566- if (downloadLimit != null ) {
1567- contentValues .put (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_LIMIT , downloadLimit .getLimit ());
1568- contentValues .put (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_COUNT , downloadLimit .getCount ());
1569- } else {
1570- contentValues .putNull (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_LIMIT );
1571- contentValues .putNull (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_COUNT );
1572- }
1568+ setDownloadLimitToContentValues (contentValues , downloadLimit );
15731569
15741570 contentValues .put (ProviderTableMeta .OCSHARES_ATTRIBUTES , share .getAttributes ());
15751571
@@ -1598,33 +1594,60 @@ private OCShare createShareInstance(Cursor cursor) {
15981594 share .setShareLink (getString (cursor , ProviderTableMeta .OCSHARES_SHARE_LINK ));
15991595 share .setLabel (getString (cursor , ProviderTableMeta .OCSHARES_SHARE_LABEL ));
16001596
1601- FileDownloadLimit downloadLimit = new FileDownloadLimit ( token ,
1602- getInt ( cursor , ProviderTableMeta . OCSHARES_DOWNLOADLIMIT_LIMIT ),
1603- getInt ( cursor , ProviderTableMeta . OCSHARES_DOWNLOADLIMIT_COUNT ) );
1604- share . setFileDownloadLimit ( downloadLimit );
1597+ FileDownloadLimit fileDownloadLimit = getDownloadLimitFromCursor ( cursor , token );
1598+ if ( fileDownloadLimit != null ) {
1599+ share . setFileDownloadLimit ( fileDownloadLimit );
1600+ }
16051601
16061602 share .setAttributes (getString (cursor , ProviderTableMeta .OCSHARES_ATTRIBUTES ));
16071603
16081604 return share ;
16091605 }
16101606
1611- private void resetShareFlagsInAllFiles ( ) {
1612- ContentValues cv = new ContentValues ();
1613- cv .put (ProviderTableMeta .FILE_SHARED_VIA_LINK , Boolean . FALSE );
1614- cv .put (ProviderTableMeta .FILE_SHARED_WITH_SHAREE , Boolean . FALSE );
1615- String where = ProviderTableMeta . FILE_ACCOUNT_OWNER + "=?" ;
1616- String [] whereArgs = new String []{ user . getAccountName ()};
1607+ private void setDownloadLimitToContentValues ( ContentValues contentValues , FileDownloadLimit downloadLimit ) {
1608+ if ( downloadLimit != null ) {
1609+ contentValues .put (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_LIMIT , downloadLimit . getLimit () );
1610+ contentValues .put (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_COUNT , downloadLimit . getCount () );
1611+ return ;
1612+ }
16171613
1618- if (getContentResolver () != null ) {
1619- getContentResolver ().update (ProviderTableMeta .CONTENT_URI , cv , where , whereArgs );
1614+ contentValues .putNull (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_LIMIT );
1615+ contentValues .putNull (ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_COUNT );
1616+ }
16201617
1621- } else {
1622- try {
1623- getContentProviderClient ().update (ProviderTableMeta .CONTENT_URI , cv , where , whereArgs );
1624- } catch (RemoteException e ) {
1625- Log_OC .e (TAG , "Exception in resetShareFlagsInAllFiles" + e .getMessage (), e );
1626- }
1618+ @ Nullable
1619+ private FileDownloadLimit getDownloadLimitFromCursor (Cursor cursor , String token ) {
1620+ if (token == null || cursor == null ) {
1621+ return null ;
16271622 }
1623+
1624+ int limit = getIntOrDefault (cursor , ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_LIMIT );
1625+ int count = getIntOrDefault (cursor , ProviderTableMeta .OCSHARES_DOWNLOADLIMIT_COUNT );
1626+ if (limit != DEFAULT_CURSOR_INT_VALUE && count != DEFAULT_CURSOR_INT_VALUE ) {
1627+ return new FileDownloadLimit (token , limit , count );
1628+ }
1629+
1630+ return null ;
1631+ }
1632+
1633+ /**
1634+ * Retrieves an integer value from the specified column in the cursor.
1635+ * <p>
1636+ * If the column does not exist (i.e., {@code cursor.getColumnIndex(columnName)} returns -1),
1637+ * this method returns {@code -1} as a default value.
1638+ * </p>
1639+ *
1640+ * @param cursor The Cursor from which to retrieve the value.
1641+ * @param columnName The name of the column to retrieve the integer from.
1642+ * @return The integer value from the column, or {@code -1} if the column is not found.
1643+ */
1644+ private int getIntOrDefault (Cursor cursor , String columnName ) {
1645+ int index = cursor .getColumnIndex (columnName );
1646+ if (index == DEFAULT_CURSOR_INT_VALUE ) {
1647+ return DEFAULT_CURSOR_INT_VALUE ;
1648+ }
1649+
1650+ return cursor .getInt (index );
16281651 }
16291652
16301653 private void resetShareFlagsInFolder (OCFile folder ) {
@@ -1743,6 +1766,67 @@ public void removeShare(OCShare share) {
17431766 }
17441767 }
17451768
1769+ public void saveSharesFromRemoteFile (List <RemoteFile > shares ) {
1770+ if (shares == null || shares .isEmpty ()) {
1771+ return ;
1772+ }
1773+
1774+ // Prepare reset operations
1775+ Set <String > uniquePaths = new HashSet <>();
1776+ for (RemoteFile share : shares ) {
1777+ uniquePaths .add (share .getRemotePath ());
1778+ }
1779+
1780+ ArrayList <ContentProviderOperation > resetOperations = new ArrayList <>();
1781+ for (String path : uniquePaths ) {
1782+ resetShareFlagInAFile (path );
1783+ var removeOps = prepareRemoveSharesInFile (path , new ArrayList <>());
1784+ if (!removeOps .isEmpty ()) {
1785+ resetOperations .addAll (removeOps );
1786+ }
1787+ }
1788+ if (!resetOperations .isEmpty ()) {
1789+ applyBatch (resetOperations );
1790+ }
1791+
1792+ // Prepare insert operations
1793+ ArrayList <ContentProviderOperation > insertOperations = prepareInsertSharesFromRemoteFile (shares );
1794+ if (!insertOperations .isEmpty ()) {
1795+ applyBatch (insertOperations );
1796+ }
1797+ }
1798+
1799+ /**
1800+ * Prepares a list of ContentProviderOperation insert operations based on share information
1801+ * found in the given iterable of RemoteFile objects.
1802+ * <p>
1803+ * Each RemoteFile may have multiple share entries (sharees), and for each one,
1804+ * a corresponding ContentProviderOperation is created for insertion into the shares table.
1805+ *
1806+ * @param remoteFiles An iterable list of RemoteFile objects containing sharee data.
1807+ * @return A list of ContentProviderOperation objects for batch insertion into the content provider.
1808+ */
1809+ private ArrayList <ContentProviderOperation > prepareInsertSharesFromRemoteFile (Iterable <RemoteFile > remoteFiles ) {
1810+ final ArrayList <ContentValues > contentValueList = new ArrayList <>();
1811+ for (RemoteFile remoteFile : remoteFiles ) {
1812+ final var contentValues = ShareeEntry .Companion .getContentValues (remoteFile , user .getAccountName ());
1813+ if (contentValues == null ) {
1814+ continue ;
1815+ }
1816+ contentValueList .addAll (contentValues );
1817+ }
1818+
1819+ ArrayList <ContentProviderOperation > operations = new ArrayList <>();
1820+ for (ContentValues contentValues : contentValueList ) {
1821+ operations .add (ContentProviderOperation
1822+ .newInsert (ProviderTableMeta .CONTENT_URI_SHARE )
1823+ .withValues (contentValues )
1824+ .build ());
1825+ }
1826+
1827+ return operations ;
1828+ }
1829+
17461830 public void saveSharesDB (List <OCShare > shares ) {
17471831 ArrayList <ContentProviderOperation > operations = new ArrayList <>();
17481832
@@ -1759,20 +1843,26 @@ public void saveSharesDB(List<OCShare> shares) {
17591843 // Add operations to insert shares
17601844 operations = prepareInsertShares (shares , operations );
17611845
1846+ if (operations .isEmpty ()) {
1847+ return ;
1848+ }
1849+
17621850 // apply operations in batch
1763- if (operations .size () > 0 ) {
1764- Log_OC .d (TAG , String .format (Locale .ENGLISH , SENDING_TO_FILECONTENTPROVIDER_MSG , operations .size ()));
1765- try {
1766- if (getContentResolver () != null ) {
1767- getContentResolver ().applyBatch (MainApp .getAuthority (), operations );
1851+ Log_OC .d (TAG , String .format (Locale .ENGLISH , SENDING_TO_FILECONTENTPROVIDER_MSG , operations .size ()));
1852+ applyBatch (operations );
1853+ }
17681854
1769- } else {
1770- getContentProviderClient ().applyBatch (operations );
1771- }
1855+ private void applyBatch (ArrayList <ContentProviderOperation > operations ) {
1856+ try {
1857+ if (getContentResolver () != null ) {
1858+ getContentResolver ().applyBatch (MainApp .getAuthority (), operations );
17721859
1773- } catch ( OperationApplicationException | RemoteException e ) {
1774- Log_OC . e ( TAG , EXCEPTION_MSG + e . getMessage (), e );
1860+ } else {
1861+ getContentProviderClient (). applyBatch ( operations );
17751862 }
1863+
1864+ } catch (OperationApplicationException | RemoteException e ) {
1865+ Log_OC .e (TAG , EXCEPTION_MSG + e .getMessage (), e );
17761866 }
17771867 }
17781868
@@ -1830,8 +1920,7 @@ public void saveSharesInFolder(ArrayList<OCShare> shares, OCFile folder) {
18301920 * @param operations List of operations
18311921 * @return
18321922 */
1833- private ArrayList <ContentProviderOperation > prepareInsertShares (
1834- Iterable <OCShare > shares , ArrayList <ContentProviderOperation > operations ) {
1923+ private ArrayList <ContentProviderOperation > prepareInsertShares (Iterable <OCShare > shares , ArrayList <ContentProviderOperation > operations ) {
18351924
18361925 ContentValues contentValues ;
18371926 // prepare operations to insert or update files to save in the given folder
0 commit comments