如何检索文件的修改日期?

时间:2013-06-27 14:29:46

标签: java box-api last-modified

在我的程序中,我试图获取我的盒子文件夹中某些项目的最后修改日期,但我无法访问该信息。

根据盒子API的文档和java库的javadoc,BoxTypedObject的以下任何方法都应该返回我想要的信息:

  • getModifiedAt()应该以ISO 8601格式返回String日期。
  • getModifiedDate()应该返回日期的Date对象。
  • getValue("modified_at")还应该以ISO 8601格式返回String日期。
  • getExtraData("modified_at")也是一种可能的方式,虽然我对此不太确定。

然而,这些方法都没有对我有用;他们都只是回归null

我用来检索日期的(大大简化的)代码如下,上面的方法之一替换了注释块:

private static void printAll(BoxFolder boxFolder){
    for(BoxTypedObject file : boxFolder.getItemCollection().getEntries())
        System.out.printf("[\"%1$s\" %2$s]%n",
                file.getValue("name"), file./*[???]*/);
}

其他字段都返回正确的值,只有当我尝试获取日期时它才会失败。

  

如何检索BoxTypedObject的修改日期?

编辑:我已经想出了一种方法来获得它,但它有点慢。

client.getFilesManager().getFile(file.getId(), null).getModifiedAt()

检索日期。不过,如果有更好的方法,我仍然感兴趣。


其他信息(可能与问题相关或不相关):

Box客户端的身份验证由以下类处理:

import java.awt.Desktop;
import java.io.*;
import java.net.*;
import com.box.boxjavalibv2.BoxClient;
import com.box.boxjavalibv2.dao.BoxOAuthToken;
import com.box.boxjavalibv2.exceptions.*;
import com.box.boxjavalibv2.requests.requestobjects.BoxOAuthRequestObject;
import com.box.restclientv2.exceptions.BoxRestException;

/**
 * This class handles the storage and use of authentication keys, to
 * simplify the process of obtaining n authenticated client.  This class
 * will store refresh keys in a file, so that it can authenticate a client
 * without needing for user intervention.
 * <p>
 * Copyright 2013 Mallick Mechanical, Inc.
 * 
 * @author Anson Mansfield
 */
public class Authenticator {

    /**
     * Constructs an {@code Authenticator} for use obtaining
     * authenticated {@Code BoxClient}s
     * 
     * @param key The OAuth client id and application key.
     * @param secret The OAuth client secret.
     * @param authFile The file to be used for storing authentications
     * for later use.
     */
    public Authenticator(String key, String secret, File authFile){
        this.key = key;
        this.secret = secret;
        this.authFile = authFile;
    }

    /**
     * Constructs a new {@Code BoxClient} object, authenticates it,
     * and returns it.
     */
    public BoxClient getAuthenticatedClient(){
        BoxClient client = new BoxClient(key,secret);
        client.authenticate(getToken(client));
        return client;
    }
    public final String host = "http://localhost";
    public final int port = 4000;
    public final String key, secret;
    public final File authFile;
    public final String url = "https://www.box.com/api/oauth2/authorize?response_type=code&client_id=";

    /**
     * Obtains a token that can be used to authenticate the box client,
     * and stores its refresh value in a file, so it can be used later.
     * @param client The client to obtain a token for.
     * @return A token that can be used to authenticate the client, or
     * {@code null} if one could not be obtained.
     */
    private BoxOAuthToken getToken(BoxClient client){
        BoxOAuthToken token = null;
        try{
            if((token = getOldToken(client)) != null) return token;
            if((token = getNewToken(client)) != null) return token;
            return token;
        }finally{
            writeNewToken(token);
        }
    }

    /**
     * Attempts to write a token's refresh token to a file.
     * @param token The token whose refresh value is to be written.
     */
    private void writeNewToken(BoxOAuthToken token) {
        if(token != null)
            try(BufferedWriter out = new BufferedWriter(new FileWriter(authFile))){
                out.write(token.getRefreshToken());
            }catch(IOException ex){
                System.out.println("couldn't update new token");
            }
    }

    /**
     * Reads the last session's refresh token from a file and attempts
     * to get a new authentication token with it.
     * @param client The client for which the authentication token is for.
     * @return The token obtained from the refresh, or {@code null} if one
     * could not be obtained.
     */
    private BoxOAuthToken getOldToken(BoxClient client) {
        System.out.println("attempting to use old token");
        BoxOAuthToken token = null;
        try(BufferedReader in = new BufferedReader(new FileReader(authFile))){
            token = client.getOAuthManager().refreshOAuth(
                    BoxOAuthRequestObject.refreshOAuthRequestObject(
                            in.readLine(), key, secret
                            ));
            System.out.println("refreshed old token");
        }catch(IOException ex){
            System.out.println("couldn't read old token");
        } catch(BoxRestException | BoxServerException | AuthFatalFailureException ex){
            System.out.println("couldn't refresh old token");
        }
        return token;
    }

    /**
     * Connects to the OAuth server and gets a new authentication token.
     * @param client The client to get a token for.
     * @return The new token obtained from the server, or {@code null} if one could not be obtained.
     */
    private BoxOAuthToken getNewToken(BoxClient client) {
        System.out.println("attempting to get new token");
        BoxOAuthToken token = null;
        try {
            Desktop.getDesktop().browse(java.net.URI.create(url + key));
            token = client.getOAuthManager().createOAuth(
                    BoxOAuthRequestObject.createOAuthRequestObject(getCode(), key, secret, host + port)
                    );
        } catch (BoxRestException | BoxServerException |  AuthFatalFailureException | IOException ex) {
            ex.printStackTrace();
            return null;
        }
        return token;
    }

    /**
     * This listens on the configured port for the code included in the callback.
     * It also deploys a script on the receiving socket to close the browser tab navigating to it.
     * @return The authentication code to generate a token with.
     */
    private String getCode(){
        try (ServerSocket serverSocket = new ServerSocket(port);
                Socket socket = serverSocket.accept();
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream());){
            out.println("<script type=\"text/javascript\">");
            out.println(    "window.open('', '_self', '');");
            out.println(    "window.close();");
            out.println("</script>"); //Close the tab
            while (true){
                String code = "";
                code = in.readLine ();
                System.out.println(code);
                String match = "code";
                int loc = code.indexOf(match);
                if( loc >0 ) {
                    int httpstr = code.indexOf("HTTP")-1;
                    code = code.substring(code.indexOf(match), httpstr);
                    String parts[] = code.split("=");
                    code=parts[1];
                    return code;
                } else {
                    // It doesn't have a code
                }
            }
        } catch (IOException | NullPointerException e) {
            return "";
        }
    }
}

将获得修改字段的实际类(但尚未完成):

import java.io.File;
import java.util.Scanner;
import com.box.boxjavalibv2.BoxClient;
import com.box.boxjavalibv2.dao.BoxFolder;
import com.box.boxjavalibv2.dao.BoxTypedObject;

/**
 * Copyright 2013 Mallick Mechanical, Inc.
 * 
 * @author Anson Mansfield
 */
public class BoxStuff {
    static BoxClient client;
    public void main(String ... args) throws Exception {
        client = new Authenticator(args[0], args[1], new File(args[2]))
        .getAuthenticatedClient();
        userSelectFolder("Select the project folder");
    }
    private static BoxFolder userSelectFolder(String prompt) throws Exception{
        Scanner kbd;
        if(System.console()!=null)
            kbd = new Scanner(System.console().reader());
        else
            kbd = new Scanner(System.in);

        String line = "";

        System.out.println();
        System.out.println(prompt);
        System.out.println("(leave prompt blank to select folder)");
        BoxFolder current = client.getFoldersManager().getFolder("0", null);
        printAll(current);
        System.out.print("select>");
        while(!(line = kbd.nextLine()).isEmpty()){
            BoxFolder next = select(current, Integer.parseInt(line));
            if(next != null) current = next;
            printAll(current);
            System.out.print("select>");
        }
        return current;
    }
    private static void printAll(BoxFolder boxFolder){
        int idx=0;
        System.out.println("  0:[parent folder]");
        for(BoxTypedObject file : boxFolder
                .getItemCollection()
                .getEntries()){
            if(file.getType().equals("folder")){
                System.out.printf("%1$3d:[%2$-32s %3$-6s %4$-9s]%n",
                        ++idx, format((String) file.getValue("name"),30), file.getType(), file.getId());
            } else {
                System.out.printf("    [%1$-32s %2$-6s %3$-9s Edit:%4$s]%n",
                        format((String) file.getValue("name"),32), file.getType(), file.getId(), file.getExtraData("modified_at"));
            }
        }
    }
    private static String format(CharSequence source, int length){
        StringBuilder b = new StringBuilder(length);

        b.append('"');

        if(source.length() > 30)
            b.append(source.subSequence(0, 29)).append('~');
        else
            b.append(String.format("%1$-30s",source));
        b.append('"');
        return b.toString();
    }
    private static BoxFolder select(BoxFolder boxFolder, int i) throws Exception{
        int idx=0;
        for(BoxTypedObject file : boxFolder.getItemCollection().getEntries()){
            if(file.getType().equals("folder") && ++idx == i){
                return client.getFoldersManager().getFolder(file.getId(), null);
            }
        }

        if(idx==0){
            if(boxFolder.getParent() == null)
                return client.getFoldersManager().getFolder("0", null);
            else
                return client.getFoldersManager().getFolder(boxFolder.getParent().getId(), null);
        }else{
            System.out.println("Selection is out of range!");
            return boxFolder;
        }
    }
}

如果有人想要将这些课程用于某事,请问我。它可能是好的(他们是机械承包商,而不是软件公司),我只需要与我的老板清楚(这段代码仍然属于公司)。

2 个答案:

答案 0 :(得分:6)

这实际上有点棘手。默认情况下,获取文件夹项的api调用仅返回具有一些默认字段的子项,它们不包括modified_at等字段。但是,如果您提供额外的字段参数,您应该能够获得它们。

以下是使用getFolderItems方法时可以执行的操作(这也在github中的自述文件中): BoxFolderRequestObject requestObj = BoxFolderRequestObject.getFolderItemsRequestObject(30, 20) .addField(BoxFolder.FIELD_NAME) .addField(BoxFolder.FIELD_MODIFIED_AT); BoxCollection collection = boxClient.getFoldersManager().getFolderItems(folderId, requestObj);

此处还有另一个棘手的问题,在提供这些字段后,结果子项只包含提供的字段(加上一些基本字段),因此请确保添加所需的所有字段。

答案 1 :(得分:0)

这是我想出来的一种方式(实际上有效):

client.getFilesManager().getFile(file.getId(), null).getModifiedAt()

然而,这有点慢,所以如果其他人知道更快的解决方案,我将非常感激。