• 寺田さんへお願い

    By Muneyuki Ohkawa 1 decade ago

    寺田さん、お疲れ様です。



    GoogleCalendarDAOのgetFirstEntryとgetNextEntryの組み合わせで、指定日以降のカレンダーを順次取得していけるはずなのですが、どうもうまく取得できていないようです。特に、getFirstEntryが、指定日よりもずいぶん先の予定を取得してきてしまっています。



    テストデータでは今まで全然気づかなかったのですが、私の本番カレンダーをGooCalSyncで運用している中で、Notes側を削除しているのにGoogle側のカレンダーが削除されない現象が見られ、原因がここにあることがわかりました。



    この部分の修正をお願いできないでしょうか。

    • これでどうでしょうか。

      By Muneyuki Ohkawa 1 decade ago

      寺田さん、私の方でも調べてみました。



      おっしゃるように、繰り返しカレンダーのハンドリングが1つの原因でうまくいっていないようです。

      カレンダーの並べ変えのロジックをWhenオブジェクトを参照して行っていますが、繰り返しカレンダーは、Whenオブジェクトを持っていないので、正常に動作しないことになります。



      getFirstEntryメソッドを以下のように修正してみました。

      修正方法として、並べ替えはCalendarQueryクラスへのパラメータとして実装しました。また、最大取得エントリー数の設定も必要で、いままでは20個程度しか取得できていませんでした。

      ご確認いただけますでしょうか。




      public BaseDoc getFirstEntry(String syncStartDate) {<br/>
          <br/>
          Settings mySets = Factory.getSettings();<br/>
          URL entryUrl;<br/>
          workEntry = null;<br/>
          try {<br/>
      

      entryUrl = new URL("http://www.google.com/calendar/feeds/" + mySets.getGoogleAccountName() + "/private/full/");

              CalendarService cs = Factory.getCalendarService();<br/>
              <br/>
             // Set query parameters to specify <br/>
             //    Date from which GooCalSync start synchronize calendar entries.<br/>
             //    Calendar entry order to be sorted starttime and ascending.<br/>
             //    maximun number of entries received. 65535 is set so that all entries could be retrieved actually.<br/>
             //    recurrence calendar entry retrieved as single entry with recurrence information.<br/>
              CalendarQuery myQuery = new CalendarQuery(entryUrl);            <br/>
              myQuery.setMinimumStartTime(DateTime.parseDateTime(syncStartDate)); <br/>
              myQuery.setStringCustomParameter(&quot;orderby&quot;, &quot;starttime&quot;);<br/>
              myQuery.setStringCustomParameter(&quot;sortorder&quot;, &quot;ascending&quot;);<br/>
              myQuery.setMaxResults(65535);<br/>
              myQuery.setStringCustomParameter(&quot;singleevents&quot;, &quot;false&quot;);<br/>
              <br/>
              CalendarEventFeed workFeed = (CalendarEventFeed) cs.query(myQuery, CalendarEventFeed.class);<br/>
              counter = 0;<br/>
              <br/>
              if (workFeed == null) {<br/>
                  return null;<br/>
              } else {<br/>
                  workFeedList = workFeed.getEntries();<br/>
                  if (workFeedList.size() &gt; counter) {<br/>
                      <br/>
                     // Commented by M.Ohkawa.<br/>
                     // This sort logic could not handle recurrence entries.<br/>
                     // Sorting should be treated by Google API.<br/>
                     //Collections.sort(workFeedList,new CalendarComparator());<br/>
                      <br/>
                      workEntry = workFeedList.get(counter);<br/>
                      counter++;<br/>
                      return convEntry(workEntry);    <br/>
                  } else {<br/>
                      return null;<br/>
                  }<br/>
              }<br/>
          } catch (ResourceNotFoundException e) {<br/>
              return null;<br/>
          } catch (MalformedURLException e) {<br/>
              e.printStackTrace();<br/>
              System.exit(-1);<br/>
          } catch (IOException e) {<br/>
              e.printStackTrace();<br/>
              System.exit(-1);<br/>
          } catch (ServiceException e) {<br/>
              e.printStackTrace();<br/>
              System.exit(-1);<br/>
          }<br/>
          return null;<br/>
      }
      
      • ありがとうございます。

        By Junya Terada 1 decade ago

        たぶん、大丈夫だと思います。

        1点私が気にしていた点がありまして、

        myQuery.setStringCustomParameter("singleevents", "false");



        とすると、繰り返しEntryが展開されないつまり、繰り返しのはじめの日 < 検索する開始日

        の場合、検索結果にHitしないのではと危惧していたため、データをいろいろ分析しようと思っていました。

        ただ、trueにすることで、何度も何度も同じ繰り返しエントリを処理するようになっても嫌だなと思っていました。

        • singleevents=false

          By Muneyuki Ohkawa 1 decade ago

          繰り返しEntryは、展開されないようにしたいのです。

          展開されてしまうと、Recurrenceオブジェクトが落ちてしまって、繰り返しではなく、個々のカレンダーエントリになってしまいます。GooCalSync.nsf上のIDマッピングテーブルは、1対1を前提としているので、展開されないようにしています。デフォルトはfalseなのですが、大事な部分なので、一応、明示的にfalseを指定しています。



          ”繰り返しのはじめの日 < 検索する開始日” の問題はあるかもしれませんが、現在のGooCalSyncの仕様では、繰り返しカレンダーをGoogleからNotesへ同期させることは止めています。やろうとすると、Warningを出すようにしています。これは、結局、iCalendarの繰り返しの仕様が複雑すぎて、対応するとすると、時間がかかりすぎると判断したためです。

        • もう1点気になったところが

          By Junya Terada 1 decade ago

          私の環境だけなのかもしれませんが、挙動が不思議だったので、確認したのですが、GooCalUtilのconvXStoNotesDateTimeで、試したところ月と日が逆転してしまっていて・・・・

          Notesが悪さしている可能性があります。以上今のところ気がついた点です。



          2009/06/03 15:44:03 DEBUG — Retrieved Google calendar entry —

          2009/06/03 15:44:03 DEBUG ID : 152em9l8nqcpnpeu3o78uamki4

          2009/06/03 15:44:03 DEBUG Title : テスト

          2009/06/03 15:44:03 DEBUG Content : テストです。

          2009/06/03 15:44:03 DEBUG startDateTime : 2009-06-01T11:00:00.000+09:00

          2009/06/03 15:44:03 DEBUG endDateTime : 2009-06-01T12:30:00.000+09:00

          2009/06/03 15:44:03 DEBUG location : RN08

          2009/06/03 15:44:03 DEBUG lastupdated : 2009-06-01T19:26:27.000Z

          2009/06/03 15:44:03 DEBUG apptype : 0

          2009/06/03 15:44:03 DEBUG ————————————–

          2009/06/03 15:44:03 DEBUG executing insert

          2009/06/03 15:44:03 DEBUG convXStoNotesDateTime : 2009-06-01T11:00:00.000+09:00 -> 2009/01/06 11:00:00 ZE9

          2009/06/03 15:44:03 DEBUG convXStoNotesDateTime : 2009-06-01T12:30:00.000+09:00 -> 2009/01/06 12:30:00 ZE9



          試したコード


          public static lotus.domino.DateTime convXStoNotesDateTime(String org) {<br/>
              try {   <br/>
                  lotus.domino.DateTime dt = Factory.getNotesSession().createDateTime(org.substring(5, 7)+&quot;/&quot;+org.substring(8, 10)+&quot;/&quot;+org.substring(0, 4)+&quot; &quot;+org.substring(11, 19));<br/>
                  Factory.getLog().debug(&quot;convXStoNotesDateTime : &quot; + org + &quot; -&gt; &quot; + dt.toString());<br/>
                  return dt;<br/>
              } catch (NotesException e) {<br/>
                  e.printStackTrace();<br/>
                  System.exit(-1);<br/>
              }<br/>
              return null;<br/>
          }
          
          • 別の方からも指摘がありました。

            By Muneyuki Ohkawa 1 decade ago

            寺田さんの環境もそうなのですか。

            Notesは6.5ですか?8.0や8.5は大丈夫なんですよね。

            java.util.Calendarを経由して日付変換するように修正してみました。

            Google to Notesの問題も含め、v0.914としてアップしますので、試してみてください。

            • 8.0を使っています。

              By Junya Terada 1 decade ago

              8.0でテストしていまして起きていました。



              Fix版で問題なく動きました。



              また、いくつかお願いがあるのですが、まず、GoogleCalendarDAO.javaのconvEntryメソッドところで、AllDay Eventの場合、時間を付けているのですが、ミリ秒も付けてはいかがでしょうか?

              bd.setStartDateTime(sdt.toString() + "T00:00:00+00:00");



              bd.setStartDateTime(sdt.toString() + "T00:00:00.000+00:00");



              狙いとしては、↓のように、SimpleDateFormatで解析してしまおうかと・・・(ただし先ほど出てた五午前午後問題は別途調査が必要ですが)substringをやるより実用性があるのかなと・・・

              public static lotus.domino.DateTime convXStoNotesDateTime(String org) {<br/>
                  try {<br/>
                      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(&quot;yyyy-MM-dd'T'HH:mm:ss.SSSZ&quot;);<br/>
              


                      Calendar cal = Calendar.getInstance();<br/>
                      cal.setTime(sdf.parse(org));<br/>
              


                      lotus.domino.DateTime dt = Factory.getNotesSession().createDateTime(cal);<br/>
                      Factory.getLog().debug(&quot;convXStoNotesDateTime : &quot; + org + &quot; -&gt; &quot; + dt.toString());<br/>
                      <br/>
                      return dt;<br/>
                      <br/>
                  } catch (NotesException e) {<br/>
                      e.printStackTrace();<br/>
                      System.exit(-1);<br/>
                  } catch (java.text.ParseException pe){<br/>
                      pe.printStackTrace();<br/>
                      System.exit(-1);<br/>
                  }<br/>
                  return null;<br/>
              }
              
              • なるほど、こんなやり方があるんですね。

                By Muneyuki Ohkawa 1 decade ago

                BaseDocのstartDateTimeは、xs:dateフォーマット(例:2009-05-20T12:00:00+09:00)で格納されていることを前提に、いろんなコードが動いているので、今、格納形式を変えるのはリスクが大きすぎて難しいです。タイムゾーンの情報も必要です。



                ただ、今のconvXStoNotesDateTimeを、java.text.SimpleDateFormatを使ってもっと効率的に書き直すことはできそうですね。プライオリティは低めですが、すぐ出来そうなので、やってみます。



                また、中国語のAM/PMが入る問題は、GooCalUtil.convNotesDateTimeToXSメソッド中の"orgTime = org.getTimeOnly();"が原因だと考えています。多分、ロケールによっては、24時間表記とならないのでしょう。ロケールに依存しないコードに変更する必要がありますね。

                • 了解です。

                  By Junya Terada 1 decade ago

                  Google-> Notesをやっていて、ミリ秒まで入ってきていたので、文字列の長さで

                  "yyyy-MM-dd'T'HH:mm:ss.SSSZ"で解析するか、"yyyy-MM-dd'T'HH:mm:ssZ"で解析するかを振り分ければよさそうですね。